What is the "commit" section used for?
The commit clause is identical in format and operation to the access
clause (except it starts with "commit" instead of "access").
The only difference is that all access clauses are executed before any
commit clause executes. This provides a two-phase creation cycle that is useful for
preventing unintentional recycling of allocated and de-allocated resources.
For example, if we wanted a buffer pointer to point to a buffer that has
been freed, we would free the buffer in the commit phase. This insures that
the buffer is freed immediately before the buffer pointer is used, preventing
the memory from being reallocated before _theVariable is used. For example,
imagine you wanted to test memcpy(to,from,n). Suppose to was supposed to
point to a freed buffer. Suppose we allocate the "to" buffer and
free it in the access phase. Then we allocate "from" in access
as well. The compiler might well allocate the memory for "from"
in the same region of memory that "to" had been allocated in.
Instead of "to" now pointing to a freed region, "to"
points to the region of memory that "from" points to, which is
probably not the scenario you intended to test.
A better way is to allocate both the buffers, then free "to" just
before calling memcpy so that "to" really points to freed memory,
just as you wanted. You can do this by calling malloc in the access phase
your buffers and calling free in the commit phase for the dial settings
that are supposed to point to freed buffers.
What is the "cleanup" section used for?
The cleanup section is simple. Use it to free any resources, like memory,
files or FIFOs that were created for particular dial settings.
let's look at the template b_ptr_buf.tpl that uses "commit", "access",
and several other features.
char *buf_ptr;
extern int main(); /* for BUF_CODE */
const int buf_SMALL = 1; /* size of small buf */
const int buf_MED = bm_PAGESIZE; /* size of medium buf */
}
//Note how we save the
location of the buffer in the global variable save_loc_bufxx.
//That way, it can be freed from the cleanup stage.
BUF_SMALL
{save_loc_bufxx = buf_ptr = (char *) malloc (buf_SMALL);
sup_fill((char *)buf_ptr, buf_SMALL);
_theVariable = buf_ptr;}
BUF_MED
{save_loc_bufxx = buf_ptr = (char *)malloc (buf_MED);
sup_fill((char *)buf_ptr, buf_MED);
_theVariable = buf_ptr;}
BUF_LARGE
{save_loc_bufxx = buf_ptr = (char *)malloc ((1 << 29) + 1);
/* don't fill this one because it takes too long */
_theVariable = buf_ptr;}
BUF_XLARGE
{save_loc_bufxx = buf_ptr = (char *)malloc ((1 << 30) + 1);
/* don't fill this one because it takes too long */
_theVariable= buf_ptr;}
BUF_HUGE
{save_loc_bufxx = buf_ptr =(char *) malloc (((unsigned long) 1 << 31) + 1);
/* don't fill this one because it takes too long */
_theVariable= buf_ptr;}
BUFMAX
{save_loc_bufxx = buf_ptr = (char *)malloc (ULONG_MAX);
/* don't fill this one because it takes too long */
_theVariable= buf_ptr;}
BUF_64k
{save_loc_bufxx = buf_ptr = (char *)malloc ((1 << 16) + 1);
sup_fill((char *)buf_ptr, (1 << 16) + 1);
_theVariable = buf_ptr;}
BUF_END_MED
{save_loc_bufxx = buf_ptr = (char *)malloc (buf_MED);
sup_fill((char *)buf_ptr, buf_MED);
_theVariable = (void *) (((unsigned long) buf_ptr) + buf_MED - 1);}
BUF_FAR_PAST
{save_loc_bufxx = buf_ptr = (char *)malloc (buf_MED);
sup_fill((char *)buf_ptr, buf_MED);
for ( int i=0 ; i<buf_MED; i++ ) *(buf_ptr++) = 'a';
_theVariable = (void *) (((unsigned long) buf_ptr) + (bm_PAGESIZE * 1000));}
BUF_ODD
{save_loc_bufxx = buf_ptr = (char *)malloc (buf_MED);
sup_fill((char *)buf_ptr, buf_MED);
_theVariable = (void *) (((unsigned long) buf_ptr) + 1);}
BUF_FREED
{save_loc_bufxx = buf_ptr = (char *)malloc (buf_MED);
sup_fill(buf_ptr, buf_MED);
for ( int i=0 ; i<buf_MED; i++ ) *(buf_ptr++) = 'a';
_theVariable= buf_ptr;}
BUF_CODE
{_theVariable = (void *) &main;
}
BUF_LOW
{_theVariable = (void *) 16;
}
]
commit
[
// For the buffer that is supposed to be freed, we free it right before we use it
BUF_FREED
{free (save_loc_bufxx);
}
]
// In the cleanup phase we free any buffers that have not been freed.
cleanup
[
{
if (save_loc_bufxx != NULL) free(save_loc_bufxx);
}
]