// Anthony int allocate(int number_of_bytes) { Node *p = HeapArray; // find a free header that fits number_of_bytes while (p < HeapArray + HEAP_SIZE) { // if free and enough space if ( is_allocated(p) == 0 && block_size(p) >= number_of_bytes) { // if we aren't allocating the whole block, // it must be split and a new header must be made if (number_of_bytes < p->size) { Node *next_header = p + number_of_bytes; set_allocated(next_header, 0); set_block_size(next_header, p->size - number_of_bytes); set_block_number(next_header, 0); } // finally, allocate the header set_allocated(p, 1); set_block_size(p, number_of_bytes); set_block_number(p, nextBlockNumber); printf("%d\n", nextBlockNumber); return nextBlockNumber++; } p = p + block_size(p); } printf("Could not allocate %d bytes.\n", number_of_bytes); return 0; }
void *malloc(size_t size) { if (0 == size) { return NULL; } size += sizeof(block_meta_t); // size requested + size of block_meta_t is total size required block_meta_t *ret = NULL; init_heap(); // check for a block on the free_list of sufficient size ret = (block_meta_t *)list_find_node_with_data(&free_list, &is_enough_room, (void *)size); // found room on free_list if (NULL != ret) { list_remove_node(&free_list, ret); // no room on free_list } else { // is there room on the last partially-used page? if (size <= remaining) { ret = last; remaining -= size; } else { // no room anywhere, get new page(s) // Allocate creates new page(s), so the memory from a prevoius page where // last and remaining refer should be saved to the free_list. // // Only save if that space can fit a block_meta_t + some bytes // else let it become dangling/unusable memory. if (remaining > sizeof(block_meta_t)) { set_block_size(last, remaining); list_insert_node_at_end(&free_list, last); last = NULL; remaining = 0; } if (0 != allocate(size, 0, (void **)&ret)) { return NULL; } remaining = PAGE_SZ - (size % PAGE_SZ); } set_block_size(ret, size); last = (block_meta_t *)((unsigned char *)ret + size); } // add block to allocated_list list_insert_node_at_end(&allocated_list, ret); // need casting to make the math work correctly. return (void *)((unsigned char*)ret + sizeof(block_meta_t)); }
void _free(void * ptr){ set_unused(ptr); void *next_ptr = NEXT_BLOCK(ptr); if( next_ptr!= NULL && !IS_USED(next_ptr)){ set_block_size(ptr, BLOCK_SIZE(ptr) + BLOCK_SIZE(next_ptr)); } void* pre_ptr = pre_block(ptr); if(pre_ptr != NULL && !IS_USED(pre_ptr)){ set_block_size(pre_ptr, BLOCK_SIZE(ptr) + BLOCK_SIZE(pre_ptr)); } }
memmap_free_t* split_block(memmap_free_t* mmap_free, U32 required_size ) { memmap_t* mmap_alloc = (memmap_t*) mmap_free; U32 old_size; memmap_free_t* new_mmap_free; memmap_t* new_mmap_alloc; /* splitting is only possible if the required size of the block is less than CEIL32((current size of the block) + 32 (minimum block size) + HEADER_SIZE (for the new block)) */ if (get_block_size(mmap_alloc) < required_size + BLOCK_SIZE_MULTIPLE) return NULL; old_size = get_block_size(mmap_alloc); new_mmap_free = (memmap_free_t*) (CEIL32((U32)mmap_alloc + required_size)); new_mmap_alloc = (memmap_t*) new_mmap_free; /* If mmap_alloc wasn't the last block in memory before splitting, we need to link the newly created block to whatever used to be after mmap_alloc in memory */ if (!is_last_in_memory(mmap_alloc)) { set_next_block(new_mmap_alloc, get_next_block(mmap_alloc)); set_prev_block((memmap_t*) get_next_block(mmap_alloc), new_mmap_alloc); } // Otherwise, just link the newly created block to itself (i.e. terminate) else { set_next_block(new_mmap_alloc, new_mmap_alloc); } // Linking mmap_alloc and the newly created new_mmap_alloc set_prev_block(new_mmap_alloc, mmap_alloc); set_next_block(mmap_alloc, new_mmap_alloc); // Finally, block sizes (only mmap_alloc and new_mmap_alloc are affected) set_block_size(mmap_alloc, required_size); set_block_size(new_mmap_alloc, old_size - required_size); set_allocated(new_mmap_alloc, __FALSE); #ifdef DEBUG_MEMORY printf("split_block | old size: %d, required: %d, new sizes: %d and %d\n", old_size, required_size, get_block_size(mmap_alloc), get_block_size(new_mmap_alloc)); #endif return new_mmap_free; }
/* memmap_free_t* merge_block(memmap_free_t* mmap_left, memmap_free_t* mmap_right) Merges two contiguous block of free memory. */ memmap_free_t* merge_block(memmap_free_t* mmap_left, memmap_free_t* mmap_right) { memmap_t* mmap_left_alloc = (memmap_t*) mmap_left; memmap_t* mmap_right_alloc = (memmap_t*) mmap_right; if(is_last_in_memory(mmap_right_alloc)) { set_next_block(mmap_left_alloc, mmap_left_alloc); } else { set_next_block(mmap_left_alloc, get_next_block(mmap_right_alloc)); set_prev_block(get_next_block(mmap_right_alloc), mmap_left_alloc); } #ifdef DEBUG_MEMORY printf("Left: %d, right: %d ,", get_block_size(mmap_left_alloc), get_block_size(mmap_right_alloc)); #endif remove_free_block(mmap_right); remove_free_block(mmap_left); set_block_size(mmap_left_alloc, get_block_size(mmap_left_alloc) + get_block_size(mmap_right_alloc)); #ifdef DEBUG_MEMORY printf("new left: %d\n", get_block_size(mmap_left_alloc)); #endif return mmap_left; }
/* void memmap_init(emmap_t* const mmap, U32 size) Initializes a struct of type `memmap` with a given size. */ void memmap_init(memmap_t* const mmap, U32 size) { // Initialize the values for the fields set_prev_block(mmap, mmap); set_next_block(mmap, mmap); set_block_size(mmap, size); set_allocated(mmap, __FALSE); }
void mem_initialize(){ void* ptr = HEAP_START; void* end = HEAP_END; set_unused(ptr); set_block_size(ptr,(end - ptr) + 1); initialized = 1; }
CacheMemory::CacheMemory(const dir_t &v_assoc, const dir_t &v_mem_size, const dir_t &v_block_size){ //df set_assoc(v_assoc); set_mem_size(v_mem_size); set_block_size(v_block_size); initialize(); }
void* allocate_block(void * ptr, size_t size){ size_t ex_size = BLOCK_SIZE(ptr); set_used(ptr); set_block_size(ptr, size); set_next_block(ptr, ex_size, size); return ptr + sizeof(header); }
node_t * block_split(node_t* block, size_t reqsz){ assert(block!=NULL); node_t * block_new=(node_t*)((void*)(block)+reqsz);/* split it into two free blocks */ size_t newsz=block->size-reqsz; // set_block_fprv(block->nlink, block_new); /* link each other */ if(block->nlink!=NULL){ block->nlink->plink=block_new; block_new->nlink=block->nlink; } else if(block->nlink==NULL){ block_new->nlink=NULL; } block_new->plink=block; block->nlink=block_new; set_block_size(block_new, newsz); set_block_size(block, reqsz); block_new->pprv=block; return block_new; /*return the remainder */ }
void initialize() { // statically allocate initial array HeapArray = malloc(HEAP_SIZE * sizeof(Node)); int i; for (i = 0 ; i < HEAP_SIZE ; i++) { HeapArray[i].size = 0; HeapArray[i].block_number = 0; HeapArray[i].data = '\0'; HeapArray[i].allocated = 0; } // HeapArray[0] is Header // Initial value is unallocated, size HEAP_SIZE set_block_size(HeapArray, HEAP_SIZE); }
void set_next_block(void *ptr, size_t ex_size, size_t size){ void* next = NEXT_BLOCK(ptr); set_unused(next); set_block_size(next, ex_size - size); }