0,0 → 1,152 |
/** |
* \addtogroup exampleapps |
* @{ |
*/ |
|
/** |
* \file |
* Memory block allocation routines. |
* \author Adam Dunkels <adam@sics.se> |
* |
* The memory block allocation routines provide a simple yet powerful |
* set of functions for managing a set of memory blocks of fixed |
* size. A set of memory blocks is statically declared with the |
* MEMB() macro. Memory blocks are allocated from the declared |
* memory by the memb_alloc() function, and are deallocated with the |
* memb_free() function. |
* |
* \note Because of namespace clashes only one MEMB() can be |
* declared per C module, and the name scope of a MEMB() memory |
* block is local to each C module. |
* |
* The following example shows how to declare and use a memory block |
* called "cmem" which has 8 chunks of memory with each memory chunk |
* being 20 bytes large. |
* |
\code |
MEMB(cmem, 20, 8); |
|
int main(int argc, char *argv[]) { |
char *ptr; |
|
memb_init(&cmem); |
|
ptr = memb_alloc(&cmem); |
|
if(ptr != NULL) { |
do_something(ptr); |
} else { |
printf("Could not allocate memory.\n"); |
} |
|
if(memb_free(ptr) == 0) { |
printf("Deallocation succeeded.\n"); |
} |
} |
\endcode |
* |
*/ |
|
#include <string.h> |
|
#include "memb.h" |
|
/*------------------------------------------------------------------------------*/ |
/** |
* Initialize a memory block that was declared with MEMB(). |
* |
* \param m A memory block previosly declared with MEMB(). |
*/ |
/*------------------------------------------------------------------------------*/ |
void |
memb_init(struct memb_blocks *m) |
{ |
memset(m->mem, (m->size + 1) * m->num, 0); |
} |
/*------------------------------------------------------------------------------*/ |
/** |
* Allocate a memory block from a block of memory declared with MEMB(). |
* |
* \param m A memory block previosly declared with MEMB(). |
*/ |
/*------------------------------------------------------------------------------*/ |
char * |
memb_alloc(struct memb_blocks *m) |
{ |
int i; |
char *ptr; |
|
ptr = m->mem; |
for(i = 0; i < m->num; ++i) { |
if(*ptr == 0) { |
/* If this block was unused, we increase the reference count to |
indicate that it now is used and return a pointer to the |
first byte following the reference counter. */ |
++*ptr; |
return ptr + 1; |
} |
ptr += m->size + 1; |
} |
|
/* No free block was found, so we return NULL to indicate failure to |
allocate block. */ |
return NULL; |
} |
/*------------------------------------------------------------------------------*/ |
/** |
* Deallocate a memory block from a memory block previously declared |
* with MEMB(). |
* |
* \param m m A memory block previosly declared with MEMB(). |
* |
* \param ptr A pointer to the memory block that is to be deallocated. |
* |
* \return The new reference count for the memory block (should be 0 |
* if successfully deallocated) or -1 if the pointer "ptr" did not |
* point to a legal memory block. |
*/ |
/*------------------------------------------------------------------------------*/ |
char |
memb_free(struct memb_blocks *m, char *ptr) |
{ |
int i; |
char *ptr2; |
|
/* Walk through the list of blocks and try to find the block to |
which the pointer "ptr" points to. */ |
ptr2 = m->mem; |
for(i = 0; i < m->num; ++i) { |
|
if(ptr2 == ptr - 1) { |
/* We've found to block to which "ptr" points so we decrease the |
reference count and return the new value of it. */ |
return --*ptr2; |
} |
ptr2 += m->size + 1; |
} |
return -1; |
} |
/*------------------------------------------------------------------------------*/ |
/** |
* Increase the reference count for a memory chunk. |
* |
* \note No sanity checks are currently made. |
* |
* \param m m A memory block previosly declared with MEMB(). |
* |
* \param ptr A pointer to the memory chunk for which the reference |
* count should be increased. |
* |
* \return The new reference count. |
*/ |
/*------------------------------------------------------------------------------*/ |
char |
memb_ref(struct memb_blocks *m, char *ptr) |
{ |
return ++*(ptr - 1); |
} |
/*------------------------------------------------------------------------------*/ |
|
|
|
|