www.pudn.com > UIP09_ADSP-BF537_Blackfin_org.zip > memb.c


/** 
 * \addtogroup exampleapps 
 * @{ 
 */ 
 
/** 
 * \file 
 * Memory block allocation routines. 
 * \author Adam Dunkels  
 * 
 * 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  
 
#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); 
} 
/*------------------------------------------------------------------------------*/