/// <summary> /// Does what you'd expect the malloc C standard library to do, check /// the requirements document for more details. /// <summary> /// <param name='size'> How many bytes the user needs to allocate </param> /// <return> /// A properely aligned pointer to a block of memory whose size at /// is at least equal to the size requested by the caller. /// </return> void *my_malloc(size_t size) { uint8_t *user_data; /* The pointer we will return to the user */ uint8_t *new_block; /* Used to point to the block added by grow_heap */ uint8_t *sliced_block; /* Used to point to the left-over of a block */ struct block_header *header, *footer, *slice_header; int slice_list;/* Which list the slice belongs to */ if(size <= 0) return NULL; size += sizeof(struct block_header) * 2; /* The header+footer */ size = (size+7) & ~7;/* Align the size to 8-byte boundary */ /* Identify which list to pick from */ int list_num = pick_list(size); DEBUG_PRINT("size requested: %zd\n", size); DEBUG_PRINT("List picked: %d\n", list_num); user_data = extract_free_block(list_num, size); /* If no list had enough space */ if(user_data == NULL) { if((new_block = grow_heap(size)) == NULL) { DEBUG_PRINT("%s\n", "-------------------------------------"); errno = ENOMEM; return NULL; } add_free_block_to_list(list_num, new_block); user_data = extract_free_block(list_num, size); } assert(user_data != NULL); DEBUG_PRINT("%s\n", "Found a block!"); /* If we can slice, add the left-over back to our lists */ sliced_block = slice_block(user_data, size); if(sliced_block != NULL) { slice_header = (struct block_header *) sliced_block; slice_list = pick_list(slice_header->block_size); add_free_block_to_list(slice_list, sliced_block); } /* Mark the block as allocated */ header = (struct block_header *) user_data; SET_ALLOC(header); footer = get_footer(user_data); SET_ALLOC(footer); user_data = user_data + 8;/* Now points past the header */ DEBUG_PRINT("%s\n", "-------------------------------------"); return user_data; }
/** * Allocate memory */ void* alloc(uint32_t size) { // aligned 2 if (size & 0b1) size += 1; void* cur = mstart_; for (; cur != mend_; cur = next_block(cur)) { uint32_t block_size = size_of_block(cur); if (block_size >= size && !is_allocated(cur)) { void* remain = slice_block(cur, size); uint32_t remain_size = block_size - 4 - size; // 4 bytes is for header if (remain_size > 0) { record(cur, size, kAllocated); record(remain, remain_size, kFree); } else { record(cur, block_size, kAllocated); } return reinterpret_cast<uint8_t*>(cur) + 4; } } return nullptr; }