1 #include "ucl.h" 2 3 /** 4 * Memory Management Module 5 * 6 * UCC uses a heap-based memory management strategy. The memory is 7 * allocated from a heap. When freeing a heap, the memory in the heap 8 * will be recycled into a free block list. 9 * 10 * A heap is made of a list of memory blocks. Each memory block 11 * is a chunk of memory. 12 */ 13 14 // free block list 15 static struct mblock *FreeBlocks; 16 17 /** 18 * Initialize a memory heap. 19 */ InitHeap(Heap hp)20void InitHeap(Heap hp) 21 { 22 hp->head.next = NULL; 23 hp->head.begin = hp->head.end = hp->head.avail = NULL; 24 hp->last = &hp->head; 25 } 26 27 /** 28 * This function allocates size bytes from a heap and returns 29 * a pointer to the allocated memory. 30 */ HeapAllocate(Heap hp,int size)31void* HeapAllocate(Heap hp, int size) 32 { 33 struct mblock *blk = NULL; 34 35 // the returned pointer must be suitably aligned to hold values of any type 36 size = ALIGN(size, sizeof(union align)); 37 38 blk = hp->last; 39 40 /// if the last memory block can't satisfy the request, find a big enough memory 41 /// block from the free block list, if there is no such memory block, allocate 42 /// a new memory block 43 while (size > blk->end - blk->avail) 44 { 45 if ((blk->next = FreeBlocks) != NULL) 46 { 47 FreeBlocks = FreeBlocks->next; 48 blk = blk->next; 49 } 50 else 51 { 52 int m = size + MBLOCK_SIZE + sizeof(struct mblock); 53 54 blk->next = (struct mblock *)malloc(m); 55 blk = blk->next; 56 if (blk == NULL) 57 { 58 Fatal("Memory exhausted"); 59 } 60 blk->end = (char *)blk + m; 61 } 62 63 blk->avail = blk->begin = (char *)(blk + 1); 64 blk->next = NULL; 65 hp->last = blk; 66 } 67 68 blk->avail += size; 69 70 return blk->avail - size; 71 } 72 73 /** 74 * Recycle a heap's all memory blocks into free block list 75 */ FreeHeap(Heap hp)76void FreeHeap(Heap hp) 77 { 78 hp->last->next = FreeBlocks; 79 FreeBlocks = hp->head.next; 80 InitHeap(hp); 81 } 82 83