void *freelist_alloc( size_t length ) { char buf[20]; pmeta walker = NULL; pmeta newone = NULL; /// If there isn't a block on the free list then initialize one /// This should only be the case on the first allocation request if ( lookaside[0] == NULL ) { init_freelist(); } walker = (pmeta)lookaside[0]; // Walk while looking for the smallest useable while ( walker ) { if ( walker->length < length ) { walker = walker->next; } else { break; } } if ( walker == NULL ) { //printf("no blocks found\n"); add_freelist_block( length ); return freelist_alloc(length); } else { //printf("foudn block size: $d\n", walker->length ); unlink(walker); /// If the block is less than the size needed for at /// least an 8 byte block then return the whole thing /// That means sizeof(meta) prev and next total 8 bytes /// bytes on the lookaside list if ( walker->length - length < sizeof(meta) ) { /// Skip the 4 byte length return ((char*)walker) + 4; } /// Break the chunk off newone = (pmeta) ( ((char*)walker) + 4 + length ); newone->length = walker->length - (length+4); //printf("Broke $d into $d and $d\n", walker->length, length, newone->length); walker->length = length; link(newone); //printf("Returning size: $d\n", walker->length); return ((char*)walker) + 4; } return NULL; }
/* This function initializes the memory allocator and makes a portion of ’_length’ bytes available. The allocator uses a ’_basic_block_size’ as its minimal unit of allocation. The function returns the amount of memory made available to the allocator. If an error occurred, it returns 0. */ extern unsigned int init_allocator(unsigned int _basic_block_size, unsigned int _length) { if (_basic_block_size) block_size = _basic_block_size; else block_size = default_block_size; if (_length) mem_size = _length; else mem_size = default_mem_size; init_freelist(); allocated_space = malloc(sizeof(Header) + mem_size); Header* header = allocated_space; init_Header(header); header->size = basic_logarithm(mem_size); add_header(header); return get_free_size(header); }