int main() { int a = 10; int b = 20; swap(&a,&b); char choice; pid=0; free_block = init_free_block(mem_size); //初始化空闲区 for(;;) { display_menu(); //显示菜单 fflush(stdin); choice=getchar(); //获取用户输入 switch(choice) { case '1': set_mem_size(); break; //设置内存大小 case '2': set_algorithm();flag=1; break; //设置分配算法 case '3': new_process(); flag=1; break; //创建新进程 case '4': kill_process();flag=1; break; //删除进程 case '5': display_mem_usage(); flag=1; break; //显示内存使用 case '0': do_exit(); exit(0); //释放链表并退出 default: break; } getchar(); } }
/* * mm_free - Freeing a block does nothing. */ void mm_free(void *ptr) { size_t size = GET_SIZE(HDRP(ptr)); mm_log("\nfree(%p)\n", ptr); init_free_block(ptr, size); }
static void place(void *ptr, size_t size) { mm_log("placing at %p, size %d\n", ptr, (int)size); size_t free_size = GET_SIZE(HDRP(ptr)); size_t rem = free_size - size; if (rem < DSIZE+WSIZE*2) { size = free_size; } /* Delete from the freelist */ delete_free_block(ptr); PUT(HDRP(ptr), PACK(size, 1)); PUT(FTRP(ptr), PACK(size, 1)); mm_log("header = (%d,%d)\n", GET_SIZE(HDRP(ptr)), GET_ALLOC(HDRP(ptr))); mm_log("footer = (%d,%d)\n", GET_SIZE(FTRP(ptr)), GET_ALLOC(FTRP(ptr))); /* See if we should split */ if (size != free_size) { void *split_pt = ptr + size; init_free_block(split_pt, free_size-size); } }
void *coalesce(void *hdrp) { size_t size = get_size(hdrp); size_t prev_alloc = get_prev_alloc(hdrp); // read current header to get the privous block allocate bit size_t next_alloc = get_alloc((char*)hdrp + size); // read next block header to get its allocate bit // previous and next are both allocated if (prev_alloc && next_alloc) { return hdrp; } // previous is free but next is allocated if (!prev_alloc && next_alloc) { size_t prev_bk_size = get_size((char*)hdrp - WSIZE); void *prev_hdrp = (char*)hdrp - prev_bk_size; delete_from_size_class(prev_hdrp, find_index(prev_bk_size)); // delete previous block from free list delete_from_size_class(hdrp, find_index(size)); // delete current block from free list size_t new_size = prev_bk_size + size; init_free_block(prev_hdrp, new_size); insert_into_size_class(prev_hdrp, find_index(new_size)); return (char*)prev_hdrp; } // next is free but previous is allocated if (prev_alloc && !next_alloc) { void *next_hdrp = (char*)hdrp + size; size_t next_bk_size = get_size(next_hdrp); delete_from_size_class(next_hdrp, find_index(next_bk_size)); delete_from_size_class(hdrp, find_index(size)); size_t new_size = next_bk_size + size; init_free_block(hdrp, new_size); insert_into_size_class(hdrp, find_index(new_size)); return hdrp; } // previous and next are both free size_t prev_bk_size = get_size((char*)hdrp - WSIZE); void *prev_hdrp = (char*)hdrp - prev_bk_size; void *next_hdrp = (char*)hdrp + size; size_t next_bk_size = get_size(next_hdrp); delete_from_size_class(prev_hdrp, find_index(prev_bk_size)); delete_from_size_class(next_hdrp, find_index(next_bk_size)); delete_from_size_class(hdrp, find_index(size)); size_t new_size = prev_bk_size + next_bk_size + size; init_free_block(prev_hdrp, new_size); insert_into_size_class(prev_hdrp, find_index(new_size)); return (char*)prev_hdrp; }
void *place_and_split(void *hdrp, size_t asize) { size_t bk_size = get_size(hdrp); #if HEAP_CHECK assert(bk_size >= asize); #endif delete_from_size_class(hdrp, find_index(bk_size)); size_t left_size = bk_size - asize; // pack small blocks in the front part of the heap #if BINARY_OPT if (left_size >= bk_size) { #endif if (left_size && is_align_with_min_bk_size(left_size)) { set_size(hdrp, asize); set_alloc_bit(hdrp); void *new_free_hdrp = (char*)hdrp + asize; write_word(new_free_hdrp, PREV_ALLOC); init_free_block(new_free_hdrp, left_size); insert_into_size_class(new_free_hdrp, find_index(left_size)); } else { set_alloc_bit(hdrp); set_prev_alloc_bit((char*)hdrp + bk_size); } return hdrp; #if BINARY_OPT } else { if (left_size && is_align_with_min_bk_size(left_size)) { set_size(hdrp, left_size); init_free_block(hdrp, left_size); insert_into_size_class(hdrp, find_index(left_size)); void *new_free_hdrp = (char*)hdrp + left_size; write_word(new_free_hdrp, pack(asize, 1)); set_prev_alloc_bit((char*)new_free_hdrp + asize); return new_free_hdrp; } else { set_alloc_bit(hdrp); set_prev_alloc_bit((char*)hdrp + bk_size); return hdrp; } } #endif }
/* * mm_free - Freeing a block does nothing. */ void mm_free(void *ptr) { #if HEAP_CHECK assert(ptr); delete_from_alloc_list(ptr); #endif void *head = (char*)ptr - WSIZE; size_t size = get_size(head); init_free_block(head, size); insert_into_size_class(head, find_index(size)); coalesce(head); }
void *extend_heap(size_t size, int type) { char *hdrp = NULL; size_t asize = type == 0 ? align_chunksize(size) : align_realloc_chunksize(size); if ((void*)(hdrp = mem_sbrk(asize)) == (void*)(-1)) return NULL; heap_tail += asize; hdrp = (char*)hdrp - WSIZE; // points to heap-end 0 padding init_free_block(hdrp, asize); // pack header and footer insert_into_size_class(hdrp, find_index(asize)); write_word((char*)hdrp + asize, pack(0, 1)); // write new heap-end padding return coalesce((char*)hdrp); }
main(){ char choice; pid=0; struct free_block_type * pre,* fbt; int addr=DEFAULT_MEM_START; printf("初始化可用表长度(>1):\n"); scanf("%d",&block_num); free_block = init_free_block(mem_size); //初始化空闲区 pre=free_block; block_num--; set_mem_size(pre); fbt=free_block; while(block_num>0){ addr=pre->size+pre->start_addr; pre = init_free_block(mem_size); //初始化空闲区 pre->start_addr=addr; set_mem_size(pre); fbt->next=pre; fbt=pre; block_num--; } while(1) { display_menu(); //显示菜单 fflush(stdin); choice=getchar(); //获取用户输入 switch(choice){ case '1':// set_mem_size(); break; case '2': set_algorithm();flag=1; break; case '3': new_process(); flag=1; break; case '4': kill_process(); flag=1; break; case '5': display_mem_usage(); flag=1; break; case '0':do_exit();exit(0); default: break; } } }
static void *extend_heap(size_t words) { char *bp; size_t size; /* Allocate an even number of words to maintain alignment */ size = (words % 2) ? (words+1) * WSIZE : words * WSIZE; if ((long)(bp = mem_sbrk(size)) == -1) return NULL; PUT(bp + size - WSIZE, PACK(0, 1)); /* New epilogue header */ mm_log("setting up epilogue at %p\n", bp + size); return init_free_block(bp, size); }
/* * mm_realloc - Implemented simply in terms of mm_malloc and mm_free */ void *mm_realloc(void *ptr, size_t req_size) { size_t new_size = adjust_requested_block_size(req_size); size_t size = GET_SIZE(HDRP(ptr)); mm_log("\nrealloc(%p, %d => %d)\noriginal=%d\n\n", ptr, (int)req_size, (int)new_size, (int)size); if (new_size < size) { mm_log("newsize < original! keep pointer.\n"); size_t remain = size - new_size; if (remain >= DSIZE+WSIZE*2) { PUT(HDRP(ptr), PACK(new_size, 1)); PUT(FTRP(ptr), PACK(new_size, 1)); mm_log("have some leftover (%d), which is enough for a new block.\n",(int)remain); //split void *split_pt = ptr + new_size; init_free_block(split_pt, remain); } return ptr; } /* Okay, we need to find some new space. See if there are adjacent blocks we can coalesce into */ void *new_ptr; void *prev_ftr = ptr - DSIZE; void *next_hdr = ptr + size - WSIZE; size_t extra_space = 0; char c_prev = 0; char c_next = 0; if (!GET_ALLOC(prev_ftr)) { extra_space += GET_SIZE(prev_ftr); c_prev = 1; } if (!GET_ALLOC(next_hdr)) { extra_space += GET_SIZE(next_hdr); c_next = 1; } size_t coalesced_size = extra_space + size; if (coalesced_size >= new_size) { mm_log("prev open = %d; next open = %d. together with %d, we have %d total space.\n",c_prev,c_next,(int)size,(int)coalesced_size); new_ptr = ptr; if (c_prev) { new_ptr -= GET_SIZE(prev_ftr); //move ptr back to prev block delete_free_block(new_ptr); memcpy(new_ptr, ptr, size); } if (c_next) { delete_free_block(ptr + size); } /* We can now see if there's enough room to split another block */ size_t remain = coalesced_size - new_size; if (remain >= DSIZE+WSIZE*2) { PUT(HDRP(new_ptr), PACK(new_size, 1)); PUT(FTRP(new_ptr), PACK(new_size, 1)); mm_log("have some leftover (%d), which is enough for a new block.\n",(int)remain); //split void *split_pt = new_ptr + new_size; init_free_block(split_pt, remain); } else { PUT(HDRP(new_ptr), PACK(coalesced_size, 1)); PUT(FTRP(new_ptr), PACK(coalesced_size, 1)); } return new_ptr; } mm_log("can't coalesce. have to malloc new & free this thing\n"); /* Can't coalesce. Have to malloc new & free this block :( */ new_ptr = mm_malloc(req_size); memcpy(new_ptr, ptr, size); init_free_block(ptr, size); return new_ptr; }
/* * mm_realloc - Implemented simply in terms of mm_malloc and mm_free */ void *mm_realloc(void *ptr, size_t size) { if (!ptr) { return mm_malloc(size); } if (!size) { mm_free(ptr); return NULL; } void *hdrp = get_hdrp(ptr); size_t old_size = get_size(hdrp); size_t ori_size = old_size; size_t target_size = align_with_min_bk_size(size + WSIZE); // if possible, we won't move the data, collect space in place hdrp = backward_collect(hdrp, target_size); old_size = get_size(hdrp); if (target_size <= old_size) { #if HEAP_CHECK delete_from_alloc_list(ptr); #endif size_t left_size = old_size - target_size; if (left_size && is_align_with_min_bk_size(left_size)) { set_size(hdrp, target_size); set_alloc_bit(hdrp); void *new_free_hdrp = (char*)hdrp + target_size; write_word(new_free_hdrp, PREV_ALLOC); init_free_block(new_free_hdrp, left_size); insert_into_size_class(new_free_hdrp, find_index(left_size)); } else { set_alloc_bit(hdrp); set_prev_alloc_bit((char*)hdrp + old_size); } #if HEAP_CHECK add_to_alloc_list(ptr, size, target_size); #endif return (char*)hdrp + WSIZE; } // find fit void *new_hdrp = find_fit(target_size); if (new_hdrp) { new_hdrp = place_and_split(new_hdrp, target_size); mm_memcpy((char*)new_hdrp + WSIZE, ptr, ori_size - WSIZE); mm_free(ptr); #if HEAP_CHECK add_to_alloc_list((char*)new_hdrp + WSIZE, size, target_size); #endif return (char*)new_hdrp + WSIZE; } // extend heap new_hdrp = extend_heap(target_size, 1); if (!new_hdrp) return NULL; new_hdrp = place_and_split(new_hdrp, target_size); mm_memcpy((char*)new_hdrp + WSIZE, ptr, ori_size - WSIZE); mm_free(ptr); #if HEAP_CHECK add_to_alloc_list((char*)new_hdrp + WSIZE, size, target_size); #endif return (char*)new_hdrp + WSIZE; }