//No. 2 Best fit algorithm void * ts_malloc(size_t size) { t_block b = NULL; size_t s; //s = align4(size); s = ALIGN_SIZE(size, sizeof(char*)); //find the best block b = _find_best_block (s); if (b){ //is it big enough to be split if ((b->size - s) >= (BLOCK_SIZE + sizeof(char *) )) { _split_block (b,s); } } if (!b) { b = _extend_heap(s); if (!b) { return(NULL); } } return b->data; }
//Allocates a data block of at least size size and returns it void* _kmalloc(size_t size, uint32_t align, uint32_t* phys) { uint32_t res; //If no heap exists if (blocks == NULL) { return NULL; }; _kmalloc_header* cur = blocks; _kmalloc_header* start = blocks; _kmalloc_header* end = blocks; uint32_t align_addr; uint32_t cur_size; //Search for the first available FREE block _kmalloc_main: cur_size = 0; while (cur->type != FREE) { //Extend the heap if we are out if ((cur->next) == NULL) { _extend_heap(size); }; cur = cur->next; }; //See if it forms a long enough chain of memory blocks to work with. Otherwise, go back to the above loop. start = cur; while (cur_size < (size * 2)) { cur_size += cur->size + sizeof(_kmalloc_header); if (cur->next == NULL) { _extend_heap(size); } else if (cur->next->type != FREE) { cur = cur->next; goto _kmalloc_main; }; cur = cur->next; }; //Since we went one block too far ahead, correct for it. end = cur->prev; _kmalloc_align_check: align_addr = _find_align_addr(start, cur, size, align); if (align_addr == 0) { if (cur->next == NULL) { _extend_heap(size); goto _kmalloc_align_check; } else { cur = cur->next; goto _kmalloc_main; }; } else if (align_addr != 1) { uint32_t dist = align_addr - (uint32_t)start; _merge_blocks(start, end); _split_block(start, dist - (2 * sizeof(_kmalloc_header))); start = start->next; end = start; }; //If it is more than one block, merge them all. if (start != end) { _merge_blocks(start, end); } //Otherwise, if the block is too big, split it. else if ((start->size - size) > KMALLOC_MAX_DIFF) { _split_block(start, size); }; //Mark the block as used start->type = USED; //Return the address right after the header. res = (((uint32_t)start) + sizeof(_kmalloc_header)); if (phys != NULL) { uint32_t p_n = res - _kmalloc_d_start_addr; p_n = p_n / 4096; p_n--; p_n = p_list[p_n]; *phys = (p_n * 4096) + (res % 4096); } return (void*)res; }
void _create_heap(void) { //Creates the heap by extending it to the default heap size _extend_heap(KMALLOC_MIN_HEAP); };