void umm_init_x( size_t size ) { uint32_t UMM_MALLOC_CFG_HEAP_SIZE = (size / sizeof(size_t)) * sizeof(size_t); if (UMM_MALLOC_CFG_HEAP_SIZE < (sizeof(umm_block) * 128)) fb_alloc_fail(); if (UMM_MALLOC_CFG_HEAP_SIZE > (sizeof(umm_block) * 32768)) UMM_MALLOC_CFG_HEAP_SIZE = sizeof(umm_block) * 32768; void *UMM_MALLOC_CFG_HEAP_ADDR = fb_alloc(UMM_MALLOC_CFG_HEAP_SIZE); /* init heap pointer and size, and memset it to 0 */ umm_heap = (umm_block *)UMM_MALLOC_CFG_HEAP_ADDR; umm_numblocks = (UMM_MALLOC_CFG_HEAP_SIZE / sizeof(umm_block)); memset(umm_heap, 0x00, UMM_MALLOC_CFG_HEAP_SIZE); /* setup initial blank heap structure */ { /* index of the 0th `umm_block` */ const unsigned short int block_0th = 0; /* index of the 1st `umm_block` */ const unsigned short int block_1th = 1; /* index of the latest `umm_block` */ const unsigned short int block_last = UMM_NUMBLOCKS - 1; /* setup the 0th `umm_block`, which just points to the 1st */ UMM_NBLOCK(block_0th) = block_1th; UMM_NFREE(block_0th) = block_1th; UMM_PFREE(block_0th) = block_1th; /* * Now, we need to set the whole heap space as a huge free block. We should * not touch the 0th `umm_block`, since it's special: the 0th `umm_block` * is the head of the free block list. It's a part of the heap invariant. * * See the detailed explanation at the beginning of the file. */ /* * 1th `umm_block` has pointers: * * - next `umm_block`: the latest one * - prev `umm_block`: the 0th * * Plus, it's a free `umm_block`, so we need to apply `UMM_FREELIST_MASK` * * And it's the last free block, so the next free block is 0. */ UMM_NBLOCK(block_1th) = block_last | UMM_FREELIST_MASK; UMM_NFREE(block_1th) = 0; UMM_PBLOCK(block_1th) = block_0th; UMM_PFREE(block_1th) = block_0th; /* * latest `umm_block` has pointers: * * - next `umm_block`: 0 (meaning, there are no more `umm_blocks`) * - prev `umm_block`: the 1st * * It's not a free block, so we don't touch NFREE / PFREE at all. */ UMM_NBLOCK(block_last) = 0; UMM_PBLOCK(block_last) = block_1th; } }
// returns null pointer without error if size==0 void *fb_alloc(uint32_t size) { if (!size) { return NULL; } size=((size+sizeof(uint32_t)-1)/sizeof(uint32_t))*sizeof(uint32_t);// Round Up char *result = pointer - size; char *new_pointer = result - sizeof(uint32_t); // Check if allocation overwrites the framebuffer pixels if (new_pointer < (char *) FB_PIXELS()) { fb_alloc_fail(); } *((uint32_t *) new_pointer) = size + sizeof(uint32_t); // Save size. pointer = new_pointer; return result; }