uffs_mem.c

Go to the documentation of this file.
00001 
00007 #include <string.h>
00008 
00009 #include "uffs/uffs_types.h"
00010 #include "uffs/uffs_public.h"
00011 #include "uffs/uffs_os.h"
00012 #include "uffs/uffs_mem.h"
00013 
00014 
00015 #define PFX "mem:"
00016 
00017 
00018 #define HEAP_MAGIC_SIZE 8       /* heap magic size, this block is for memory protection */
00019 
00020 
00021 
00022 
00023 /* the 'BEST FIT' arithmetic,
00024  if not defined, the arithmetic
00025  will be the 'FIRST FIT' */
00026 #define K_HEAP_ALLOCK_BEST_FIT
00027 
00028 
00029 /* page size may be: 16,32,64,128... */
00030 #define ALLOC_PAGE_BIT_OFFSET   5
00031 #define ALLOC_PAGE_SIZE         (1 << ALLOC_PAGE_BIT_OFFSET)
00032 #define ALLOC_PAGE_MASK         (ALLOC_PAGE_SIZE - 1)
00033 #define ALLOC_THRESHOLD         (ALLOC_PAGE_SIZE * 1)
00034 
00035 /* magic mummbers */
00036 #define HEAP_NODE_FREE          0x123455aa
00037 #define HEAP_NODE_ALLOCED       0xaa551234
00038 
00039 #define ALLOC_OFFSET    12
00040 
00041 /*  Heap memory node type. */
00042 typedef struct _HEAPNODE {
00043     int mark;                   /*  alloc mark  */
00044     int size;                   /*  Size of this node   */
00045     struct _HEAPNODE *prevNode; /*  private node    */
00046     struct _HEAPNODE *prevFree; /*  Link to prev free node */
00047     struct _HEAPNODE *nextFree; /*  Link to next free node */
00048 } HEAPNODE;
00049 
00050 
00051 
00052 /*
00053         p1  |-----------|
00054             |prevNode   |   NULL
00055             |mark       |   HEAP_NODE_ALLOCED
00056             |size       |   p2 - p1
00057             |prevFree   |   alloc to user
00058             |nextFree   |   not used.
00059             |           |
00060             |           |
00061         p2  |-----------|
00062             |prevNode   |   p1
00063             |mark       |   HEAP_NODE_FREE
00064             |size       |   p3 - p2
00065             |prevFree   |   NULL
00066             |nextFree   |   p5
00067             |           |
00068             |           |
00069         p3  |-----------|
00070             |prevNode   |   p2
00071             |mark       |   HEAP_NODE_ALLOCED
00072             |size       |   p4 - p3
00073             |prevFree   |   alloc to user
00074             |nextFree   |   not used.
00075             |           |
00076             |           |
00077         p4  |-----------|
00078             |prevNode   |   p3
00079             |mark       |   HEAP_NODE_ALLOCED
00080             |size       |   p5 - p4
00081             |prevFree   |   alloc to user
00082             |nextFree   |   not used.
00083             |           |
00084             |           |
00085         p5  |-----------|
00086             |prevNode   |   p4
00087             |mark       |   HEAP_NODE_FREE
00088             |size       |   p6 - p5
00089             |prevFree   |   p2
00090             |nextFree   |   NULL
00091             |           |
00092             |           |
00093         p6  |-----------|
00094 
00095 */
00096 
00097 static HEAPNODE* volatile _k_heapFreeList = NULL;
00098 static HEAPNODE * _k_heapTail_ = NULL; 
00099 static u32 _k_heap_available = 0;
00100 static u32 _minimu_heap_avaiable = 0x0fffffff;
00101 static u32 _kernel_heap_total = 0;
00102 
00103 static void HeapDeleteFromFreeList(HEAPNODE *node);
00104 static void HeapChainToFreeList(HEAPNODE *node);
00105 static void *_k_allock_node(HEAPNODE *node, int size);
00106 static void * _kmalloc_clear(int size);
00107 static int _kfree(void *block);
00108 
00109 /*
00110  *  Delete one node from free list
00111  *
00112  */
00113 static void HeapDeleteFromFreeList(HEAPNODE *node)
00114 {
00115     if(node->nextFree)
00116         node->nextFree->prevFree = node->prevFree;
00117     if(node->prevFree)
00118         node->prevFree->nextFree = node->nextFree;
00119     if(node == _k_heapFreeList)
00120         _k_heapFreeList = node->nextFree;
00121 }
00122 
00123 /*
00124  *  Chain the node to free list
00125  */
00126 static void HeapChainToFreeList(HEAPNODE *node)
00127 {
00128     node->nextFree = NULL;
00129     node->prevFree = NULL;
00130     if(_k_heapFreeList == NULL){
00131         _k_heapFreeList = node;
00132         return;
00133     }
00134     else{
00135         _k_heapFreeList->prevFree = node;
00136         node->nextFree = _k_heapFreeList;
00137         _k_heapFreeList = node;
00138     }
00139 }
00140 
00141 /*
00142  * Alloc a block with given node
00143  * If the node  is larger than the
00144  * required space plus the space needed for
00145  * a new node plus a defined threshold, then
00146  * we split it. The unused portion is put back into
00147  * the free-list.
00148  *
00149  * Attention: Irq is locked when call this routin,
00150  * so we must unlock irq when return
00151  */
00152 static void *_k_allock_node(HEAPNODE *node, int size)
00153 {
00154     HEAPNODE *newNode;
00155 
00156     if(node->size >= size + ALLOC_THRESHOLD){
00157         /*
00158          * we need to split it 
00159          */
00160         newNode = (HEAPNODE *)((u32)node + size);
00161         newNode->size = node->size - size;
00162         newNode->mark = HEAP_NODE_FREE;
00163         newNode->prevNode = node;
00164         node->size = size;
00165         /*
00166          *  chain the newNode to free list
00167          */
00168         HeapChainToFreeList(newNode);
00169                 
00170         /*
00171          *  fix the next node
00172          */
00173          ((HEAPNODE *)((u32)newNode + newNode->size))->prevNode = newNode;
00174     }
00175         
00176     /*
00177      *  allock this block
00178      */
00179     node->mark = HEAP_NODE_ALLOCED;
00180 
00181     /*
00182      *  delete the node from free list
00183      */
00184     HeapDeleteFromFreeList(node);
00185 
00186     _k_heap_available -= node->size;
00187     if(_minimu_heap_avaiable > _k_heap_available)
00188         _minimu_heap_avaiable = _k_heap_available;
00189     
00190     uffs_CriticalExit();    /* exit critical */
00191     
00192     return (void *)((u32)node + ALLOC_OFFSET);
00193 }
00194 
00195 /*
00196  * Allocate a block from heap memory.
00197  *
00198  * This functions allocates a memory block of the specified
00199  * size and returns a pointer to that block.
00200  *
00201  * The actual size of the allocated block is larger than the
00202  * requested size because of space required for maintenance
00203  * information. This additional information is invisible to
00204  * the application.
00205  *
00206  * The routine looks for the smallest block that will meet
00207  * the required size and releases it to the caller. If the
00208  * block being requested is usefully smaller than the smallest
00209  * free block then the block from which the request is being
00210  * met is split in two. The unused portion is put back into
00211  * the free-list.
00212  *
00213  * The contents of the allocated block is unspecified.
00214  * To allocate a block with all bytes set to zero use
00215  * KHeapAllocClear().
00216  *
00217  * \note Interrupts are automatically enabled, when this
00218  *       function returns.
00219  *
00220  * \param size Size of the requested memory block.
00221  *
00222  * \return Pointer to the allocated memory block if the
00223  *         function is successful or NULL if the requested
00224  *         amount of memory is not _k_heap_available.
00225  */
00226 static void *_kmalloc(int size)
00227 {
00228     HEAPNODE *node;
00229 #if defined(K_HEAP_ALLOCK_BEST_FIT)
00230     HEAPNODE *fit;
00231 #endif
00232     if(size <= 0)
00233         return NULL;    /* size is not fit */
00234         
00235     /*
00236      *  adjust size
00237      */
00238     size += ALLOC_OFFSET;
00239     if(size & ALLOC_PAGE_MASK){
00240         size += ALLOC_PAGE_SIZE;
00241         size &= ~ALLOC_PAGE_MASK;
00242     }
00243 
00244     uffs_CriticalEnter();   /* enter critical */
00245     
00246     node = _k_heapFreeList;
00247     
00248 #if defined(K_HEAP_ALLOCK_BEST_FIT)
00249     /*
00250      * Walk through the linked list of free nodes and find the best fit.
00251      */
00252     fit = NULL;
00253     while(node){
00254         /*
00255          * Found a note that fits?
00256          */
00257         if(node->size >= size){
00258             /*
00259              * If it's an exact match, we don't
00260              * search any further.
00261              */
00262             if(node->size == size){
00263                 fit = node;
00264                 break;
00265             }
00266             /*
00267              *  We search most fit one
00268              */
00269             if(fit){
00270                 if(node->size < fit->size)
00271                     fit = node;
00272             }
00273             else
00274                 fit = node;
00275         }
00276         node = node->nextFree;
00277     }
00278     
00279     if(fit){
00280         if(fit->size >= size)
00281             return _k_allock_node(fit, size);
00282     }
00283 #else
00284     while(node){
00285         if(node->size >= size)
00286             return _k_allock_node(node, size);
00287         node = node->nextFree;
00288     }
00289 #endif
00290 
00291     uffs_CriticalExit();    /* exit critical */
00292     
00293     return NULL;    /*  not found available block   */
00294 
00295 }
00296 
00297 /* Allocates an array in memory with elements initialized to 0 */
00298 static void *_kcalloc(int num, int size)
00299 {
00300     return _kmalloc_clear(num * size);
00301 }
00302 
00303 /* Realloc memory.
00304  * if the size of memblock is small then the new required size, 
00305  * alloc a new block memory, and copy the contents from the old one,
00306  * and free the old block.
00307  * if the size is zero, free the old block, and return NULL. <2004.5.8>
00308  * if the size of origin block is larger then the new required size,
00309  * then: 
00310  *   if the gap is larger then ALLOC_PAGE_SIZE, split the node, and return
00311  *      the leav memory back to free list.
00312  *   if the gap is less then ALLOC_PAGE_SIZE, just return current block.
00313  * If the given block parameter is NULL, _krealloc behaves the same as _kmalloc.
00314  */
00315 static void *_krealloc(void *block, int size)
00316 {
00317     HEAPNODE *node;
00318     HEAPNODE *newNode;
00319     void *p;    /* return pointer */
00320     int old_data_size; /* old block data size */
00321 
00322     if(block == NULL){
00323         return _kmalloc(size);
00324     }
00325     
00326     if(size == 0) {
00327         _kfree(block);
00328         return NULL;
00329     }
00330 
00331     uffs_CriticalEnter();   /* enter critical */
00332     
00333     node = (HEAPNODE *)((u32)block - ALLOC_OFFSET);
00334     old_data_size = node->size - ALLOC_OFFSET;
00335     if(node->mark != HEAP_NODE_ALLOCED || old_data_size <= 0) {
00336         uffs_CriticalExit(); /* exit critical */
00337         return NULL;    
00339     }
00340 
00341     if(old_data_size < size) {
00342         /* new size is larger then origin block, so need alloc new block */
00343         p = _kmalloc(size);
00344         if(!p) {
00345             uffs_CriticalExit(); /* exit critical */
00346             return NULL;        /* can't alloc a new block memory, fail... */
00347         }
00348 
00349         /* alloc a new block, and copy contents from origin block,
00350          * and free it finally.
00351          */
00352         memcpy(p, block, old_data_size);
00353         _kfree(block);
00354         uffs_CriticalExit(); /* exit critical */
00355         return p;
00356     }
00357     else {
00358         /* adjust size */
00359         size += ALLOC_OFFSET;
00360         if(size & ALLOC_PAGE_MASK) {
00361             size += ALLOC_PAGE_SIZE;
00362             size &= ~ALLOC_PAGE_MASK;
00363         }
00364 
00365         if(node->size - size < ALLOC_PAGE_SIZE) {
00366             /* the remain memory is too small, so just skip it */
00367             uffs_CriticalExit(); /* exit critical */
00368             return block;
00369         }
00370         else {
00371             /* the remain memory is large enough to be splited */
00372             /* we generate a new 'alloced' node there */
00373             newNode = (HEAPNODE *)((u32)node + size);
00374             newNode->prevNode = node;
00375             newNode->mark = HEAP_NODE_ALLOCED;
00376             newNode->size = node->size - size;
00377 
00378             /* split into two node now */
00379             ((HEAPNODE *)((u32)node + node->size))->prevNode = newNode;
00380             node->size = size;
00381 
00382             /* put the newNode into freeList */
00383             _kfree((void *)((u32)newNode + ALLOC_OFFSET)); 
00384 
00385             uffs_CriticalExit(); /* exit critical */
00386             return block;
00387         }
00388     }
00389 }
00390 
00391 static void * _kmalloc_clear(int size)
00392 {
00393     void *p;
00394     
00395     p = _kmalloc(size);
00396     if(p)
00397         memset(p, 0, size);
00398     return p;
00399 }
00400 
00420 static int _kfree(void *block)
00421 {
00422     HEAPNODE *node;
00423     HEAPNODE *prev;
00424     HEAPNODE *next;
00425     if (block == NULL) {
00426         return -1;  //the pointer of the memory is invalid.
00427     }
00428     uffs_CriticalEnter();   /* enter critical */
00429     
00430     node = (HEAPNODE *)((u32)block - ALLOC_OFFSET);
00431     if(node->mark != HEAP_NODE_ALLOCED || node->size <= ALLOC_OFFSET) {
00432         uffs_CriticalExit();/* exit critical */
00433         return -1;  
00435     }
00436     _k_heap_available += node->size;
00437     
00438     prev = node->prevNode;
00439     next = (HEAPNODE *)((u32)node + node->size);
00440 
00441     if(prev->mark == HEAP_NODE_FREE){
00442         /*
00443          * If there' s a free node in front of us, merge it.
00444          */
00445         prev->size += node->size;
00446         next->prevNode = prev;
00447         HeapDeleteFromFreeList(prev);
00448         node = prev;
00449     }
00450 
00451     if(next->mark == HEAP_NODE_FREE){
00452         /*
00453          * If there' s a free node following us, merge it.
00454          */
00455         node->size += next->size;
00456         ((HEAPNODE *)((u32)next + next->size))->prevNode = node;
00457         HeapDeleteFromFreeList(next);
00458     }
00459 
00460     /*
00461      *  now, we just chain the node to free list head.
00462      */
00463     node->mark = HEAP_NODE_FREE;
00464     HeapChainToFreeList(node);
00465     uffs_CriticalExit();    /* exit critical */
00466     
00467     return 0;
00468 }
00469 
00470 
00483 void uffs_InitHeapMemory(void *addr, int size)
00484 {
00485     HEAPNODE *np;
00486     
00487     
00488     if(!((u32)addr & 3)){
00489         addr = (void *)(((u32)addr) + 4);
00490         addr = (void *)(((u32)addr) & ~3);
00491     }
00492     size &= ~ALLOC_PAGE_MASK;
00493     if(size < ALLOC_PAGE_SIZE * 3) return;
00494 
00495     uffs_CriticalEnter();
00496     
00497     /* pre alloc header node, size is ALLOC_PAGE_SIZE */
00498     np = (HEAPNODE *)addr;
00499     np->size = ALLOC_PAGE_SIZE;
00500     np->mark = HEAP_NODE_ALLOCED;
00501     np->prevNode = NULL;
00502 
00503     /* pre alloc tail node, size is -1 */
00504     np = (HEAPNODE *)((u32)addr + size - ALLOC_PAGE_SIZE);
00505     np->mark = HEAP_NODE_ALLOCED;
00506     np->size = -1;
00507     np->prevNode = (HEAPNODE *)((u32)addr + ALLOC_PAGE_SIZE);
00508     _k_heapTail_ = np;
00509 
00510     /* Free list head */
00511     np = (HEAPNODE *)((u32)addr + ALLOC_PAGE_SIZE);
00512     np->mark = HEAP_NODE_FREE;
00513     np->prevNode = (HEAPNODE *)addr;
00514     np->size = size - 2 * ALLOC_PAGE_SIZE;
00515     np->nextFree = NULL;
00516     np->prevFree = NULL;
00517     _k_heapFreeList = np;
00518     _k_heap_available = np->size;
00519     _minimu_heap_avaiable = _k_heap_available;
00520     
00521     _kernel_heap_total += size;
00522 
00523     uffs_CriticalExit();
00524 }
00525 
00526 /******************************************************************************************/
00527 
00528 
00529 static void *__umalloc(uffs_memAllocator *mem, unsigned int size, HASHTBL * heapHashTbl);
00530 static void *__ucalloc(uffs_memAllocator *mem, unsigned int num, unsigned int size, HASHTBL *heapHashTbl);
00531 static void *__urealloc(uffs_memAllocator *mem, void *block, unsigned int size, HASHTBL *heapHashTbl);
00532 static int __ufree(uffs_memAllocator *mem, void *p, HASHTBL * heapHashTbl);
00533 
00534 
00536 //static HASHTBL * InitHeapMM(void)
00537 //{
00538 //  HASHTBL * heapHashTbl;
00539 //  heapHashTbl = (HASHTBL *)_kmalloc(sizeof(HEAP_MM*) * HEAP_HASH_SIZE);
00540 //  if(heapHashTbl != NULL){
00541 //      memset(heapHashTbl, 0, sizeof(HEAP_MM*) * HEAP_HASH_SIZE);
00542 //      return heapHashTbl;
00543 //  }
00544 //  else{
00545 //      return NULL;
00546 //  }
00547 //}
00548 
00549 /* release all alloced memory from hash table,
00550  * return alloced pointer nummber.
00551  */
00552 static int ReleaseHeap(uffs_memAllocator *mem, HASHTBL *heapHashTbl)
00553 {
00554     int i;
00555     int count = 0;
00556     HEAP_MM volatile * node;
00557 
00558     if(heapHashTbl == NULL) return -1;
00559     for(i = 0; i < HEAP_HASH_SIZE; i++){
00560         while((node = heapHashTbl[i]) != NULL){
00561             __ufree(mem, node->p, heapHashTbl);
00562             count++;
00563         }
00564     }
00565     _kfree(heapHashTbl);
00566     return count;
00567 }
00568 
00569 static void *uffs_malloc(uffs_memAllocator *mem, unsigned int size)
00570 {
00571     HASHTBL * heapHashTbl;
00572 
00573     if((int)size < 0) return NULL;
00574     heapHashTbl = mem->tbl;
00575     if(heapHashTbl){
00576         return __umalloc(mem, size, heapHashTbl);
00577     }
00578     else{
00579         return NULL;
00580     }
00581 }
00582 
00583 static void *uffs_calloc(uffs_memAllocator *mem, unsigned int num, unsigned int size)
00584 {
00585     HASHTBL * heapHashTbl;
00586 
00587     if((int)size < 0 || num == 0) return NULL;
00588     heapHashTbl = mem->tbl;
00589     if(heapHashTbl){
00590         return __ucalloc(mem, num, size, heapHashTbl);
00591     }
00592     else{
00593         return NULL;
00594     }
00595 }
00596 
00597 static void *uffs_realloc(uffs_memAllocator *mem, void *block, unsigned int size)
00598 {
00599     HASHTBL * heapHashTbl;
00600 
00601     if((int)size <= 0) return NULL;
00602     heapHashTbl = mem->tbl;
00603     if(heapHashTbl){
00604         return __urealloc(mem, block, size, heapHashTbl);
00605     }
00606     else{
00607         return NULL;
00608     }
00609 }
00610 
00611 /* alloc one block with given size, return the block pointer */
00612 static void *__umalloc(uffs_memAllocator *mem, unsigned int size, HASHTBL *heapHashTbl)
00613 {
00614     void *p;
00615     HEAP_MM *node;
00616     int index;
00617     
00618     /* calling kernel routin allocate bigger size memory block */
00619     p = _kmalloc(HEAP_MAGIC_SIZE + size + HEAP_MAGIC_SIZE);
00620     
00621     if(p){
00622         node = (HEAP_MM *)_kmalloc(sizeof(HEAP_MM));
00623         if(node == NULL){
00624             _kfree(p);
00625             return NULL;
00626         }
00627         p = (void *)((u32)p + HEAP_MAGIC_SIZE); /* adjust pointer first */
00628         node->p = p;
00629         node->size = size;
00630         mem->count += size;
00631         if (mem->maxused < mem->count) mem->maxused = mem->count;
00632         node->task_id = uffs_OSGetTaskId(); /* get task id */
00633         
00634         uffs_CriticalEnter();
00635         
00636         /* insert node to hash table */
00637         index = GET_HASH_INDEX(p);
00638         node->next = heapHashTbl[index];
00639         heapHashTbl[index] = node;
00640         
00641         uffs_CriticalExit();
00642         return p;   /* ok, return the pointer */
00643     }
00644     return NULL;
00645 }
00646 
00647 /* Allocates an array in memory with elements initialized to 0 */
00648 static void *__ucalloc(uffs_memAllocator *mem, unsigned int num, unsigned int size, HASHTBL *heapHashTbl)
00649 {
00650     return __umalloc(mem, num * size, heapHashTbl);
00651 }
00652 
00653 
00654 /* realloc one block with given size, return the block pointer */
00655 static void *__urealloc(uffs_memAllocator *mem, void *block, unsigned int size, HASHTBL *heapHashTbl)
00656 {
00657     void *p, *pNew;
00658     HEAP_MM *prev, *node;
00659     int index;
00660 
00661     if(block == NULL) {
00662         return __umalloc(mem, size, heapHashTbl);
00663     }
00664 
00665     if(size == 0) {
00666         __ufree(mem, block, heapHashTbl);
00667         return NULL;
00668     }
00669 
00670     /* calculate hash index */
00671     index = GET_HASH_INDEX(block);
00672 
00673     /* check whether block pointer is alloc from this heap... */
00674     uffs_CriticalEnter();
00675     node = heapHashTbl[index];
00676     prev = NULL;
00677     while(node){
00678         if(node->p == block){
00679             break; /* got it! */
00680         }
00681         prev = node;
00682         node = node->next;  /* search for next node */
00683     }
00684 
00685     if(!node) {
00686         /* not my duty :-) */
00687         uffs_CriticalExit();
00688         return NULL;
00689     }
00690 
00691     /* ok, begin call kernel API to realloc memory */
00692 
00693     p = (void *)((u32)block - HEAP_MAGIC_SIZE); /* get real pointer which kernel need */
00694     pNew = _krealloc(p, HEAP_MAGIC_SIZE + size + HEAP_MAGIC_SIZE);
00695 
00696     if(pNew == NULL) {  /* realloc fail */
00697         uffs_CriticalExit();
00698         return NULL;
00699     }
00700 
00701     if(pNew == p) {
00702         /* new block is the same as the old block */
00703         uffs_CriticalExit();
00704         return block;
00705     }
00706 
00707     /* new block is difference with old block, we need to change hash table ... */
00708     if(prev){
00709         /* prev is not the first */
00710         prev->next = node->next;
00711     }
00712     else{
00713         /* this node is the first, so.. */
00714         heapHashTbl[index] = node->next;
00715     }
00716     uffs_CriticalExit();
00717 
00718     node->p = (void *)((u32)pNew + HEAP_MAGIC_SIZE);
00719     node->size = size;
00720     node->task_id = uffs_OSGetTaskId();
00721 
00722     /* insert node into hash table */
00723     index = GET_HASH_INDEX(node->p);
00724     uffs_CriticalEnter();
00725     node->next = heapHashTbl[index];
00726     heapHashTbl[index] = node;
00727     uffs_CriticalExit();
00728 
00729     return node->p;
00730     
00731 }
00732 
00733 
00734 /* free the block, if the pointer(parameter 'p') is 
00735  * not valid(allocated by this allocate system) or error occur, return -1,
00736  * else return 0
00737  */
00738 static int __ufree(uffs_memAllocator *mem, void *p, HASHTBL *heapHashTbl)
00739 {
00740     HEAP_MM *node, *prev;
00741     
00742     if(p){  /* check the pointer */
00743         uffs_CriticalEnter();
00744         node = heapHashTbl[GET_HASH_INDEX(p)];
00745         prev = NULL;
00746         while(node){
00747             if(node->p == p){
00748                 /* we find the node, so begin to release */
00749                 if(prev){
00750                     /* this node is not the first */
00751                     prev->next = node->next;
00752                 }
00753                 else{
00754                     /* this node is the first node of hash channel */
00755                     heapHashTbl[GET_HASH_INDEX(p)] = node->next;
00756                 }
00757 
00758                 mem->count -= node->size;
00759                 
00760                 uffs_CriticalExit();
00761                 if(_kfree(node) == -1)  /* calling kernel routine release node */
00762                     return -1;          /* fail, return -1 */
00763                 
00764                 /* calling kernel routine and return */
00765                 return _kfree((void *)((u32)p - HEAP_MAGIC_SIZE)); 
00766             }
00767             prev = node;
00768             node = node->next;  /* search for next node */
00769         }
00770         uffs_CriticalExit();
00771     }
00772     return -1;
00773 }
00774 
00775 static void uffs_free(uffs_memAllocator *mem, void *block)
00776 {
00777     HASHTBL *heapHashTbl;
00778     heapHashTbl = mem->tbl;
00779     if(heapHashTbl){
00780         if (__ufree(mem, block, heapHashTbl) < 0) {
00781             uffs_Perror(UFFS_ERR_SERIOUS, PFX"Try to free unmanaged memory ?\n");
00782         }
00783     }
00784 }
00785 
00786 URET uffs_initNativeMemAllocator(uffs_Device *dev)
00787 {
00788     uffs_memAllocator * mem;
00789     mem = _kmalloc(sizeof(uffs_memAllocator));
00790     if (mem == NULL) {
00791         return U_FAIL;
00792     }
00793     //mem->tbl = InitHeapMM();
00794     memset(mem->tbl, 0, sizeof(mem->tbl));
00795     //if (mem->tbl == NULL) {
00796     //  _kfree(mem);
00797     //  return U_FAIL;
00798     //}
00799 
00800     mem->malloc = uffs_malloc;
00801     mem->realloc = uffs_realloc;
00802     mem->calloc = uffs_calloc;
00803     mem->free = uffs_free;
00804     dev->mem = mem;
00805 
00806     return U_SUCC;
00807 }
00808 
00809 int uffs_releaseNativeMemAllocator(uffs_Device *dev)
00810 {
00811     if (dev) {
00812         if (dev->mem)
00813             return ReleaseHeap(dev->mem, dev->mem->tbl);
00814     }
00815     return -1;
00816 }

Generated on Sat Mar 17 15:45:45 2007 for uffs-doc by  doxygen 1.5.0