static int skew_merge (lua_State *L) { heap *h1 = checkheap(L, 1); heap *h2 = checkheap(L, 2); lua_settop(L, 2); if (h2 == NULL) { lua_pop(L, 1); return 1; } /* h1 */ meld(h1, h2); return 1; /* h2 */ }
/* * Requires: * None. * * Effects: * Initialize the memory manager. Returns 0 if the memory manager was * successfully initialized and -1 otherwise. */ int mm_init(void) { /* Create the initial empty heap. */ //struct node *head; printf("INIT\n"); if ((heap_listp = mem_sbrk(3 * WSIZE)) == (void *)-1) return (-1); //PUT(heap_listp, 0); /* Alignment padding */ PUT(heap_listp, PACK(DSIZE, 1)); /* Prologue header */ PUT(heap_listp + (1 * WSIZE), PACK(DSIZE, 1)); /* Prologue footer */ printf("Prologue set\n"); //temp = heap_listp + (2 * WSIZE); //head = (struct node *)temp; //printf("Initialized head to be two words after the prologue start\n"); /* Insert the next and previous pointers, the head of the list */ /* Can use heap_listp + 2*WSIZE to access head of list */ /*PUT(heap_listp + (2 * WSIZE), head.next); PUT(heap_listp + (3 * WSIZE), head.previous);*/ /*head->previous = head; head->next = head; list_start = head;*/ PUT(heap_listp + (2 * WSIZE), PACK(0, 1)); /* Epilogue header */ heap_listp += (WSIZE); printf("Epilogue set\n"); /* initialize each bin pointer to -1 */ /*for (int i = 0; i < binNum; i++) { PUT(heap_listp + ((i + 2) * WSIZE), (uint64_t)(heap_listp + WSIZE)); } list_start = heap_listp + ((binNum + 2) * WSIZE); */ checkheap(1); printf("Entering extend heap\n"); /* Extend the empty heap with a free block of CHUNKSIZE bytes. */ if (extend_heap(CHUNKSIZE / WSIZE) == NULL) { printf("Failed INIT\n"); return (-1); } printf("Completed init!\n"); if (list_start == NULL) printf("List start is NULL!\n"); checkheap(1); return (0); }
static int skew_insert (lua_State *L) { heap *h = checkheap(L, 1); lua_Number v = luaL_checknumber(L, 2); heap *x, *y, *z; lua_settop(L, 3); /* heap, value [, key] */ /* insertion */ x = newheap(L, v); if (h == NULL) { /* empty heap? */ x->down = x; x->up = x->down; return 1; /* x */ } if (x->value < h->value) { /* x becomes root */ x->down = h->up; h->up = x; x->up = h->up; return 1; /* x */ } lua_settop(L, 1); /* h is the root */ if (x->value > h->up->value) { /* x becomes new lowest node in major path */ x->up = h->up; h->up = x; x->down = h->up; return 1; /* h */ } z = h->up; y = z; while (x->value < y->up->value) { heap *s; y = y->up; s = z; z = y->down; y->down = s; /* z <-> y->down */ } x->up = y->up; x->down = z; h->up = x; y->up = h->up; return 1; /* h */ }
/* * Requires: * "ptr" is either the address of an allocated block or NULL. * * Effects: * Reallocates the block "ptr" to a block with at least "size" bytes of * payload, unless "size" is zero. If "size" is zero, frees the block * "ptr" and returns NULL. If the block "ptr" is already a block with at * least "size" bytes of payload, then "ptr" may optionally be returned. * Otherwise, a new block is allocated and the contents of the old block * "ptr" are copied to that new block. Returns the address of this new * block if the allocation was successful and NULL otherwise. */ void * mm_realloc(void *ptr, size_t size) { size_t oldsize; void *newptr; /* If size == 0 then this is just free, and we return NULL. */ if (size == 0) { mm_free(ptr); return (NULL); } /* If oldptr is NULL, then this is just malloc. */ if (ptr == NULL) return (mm_malloc(size)); newptr = mm_malloc(size); /* If realloc() fails the original block is left untouched */ if (newptr == NULL) return (NULL); /* Copy the old data. */ oldsize = GET_SIZE(HDRP(ptr)); if (size < oldsize) oldsize = size; memcpy(newptr, ptr, oldsize); /* Free the old block. */ mm_free(ptr); checkheap(1); return (newptr); }
/* * Requires: * "bp" is the address of a free block that is at least "asize" bytes. * * Effects: * Place a block of "asize" bytes at the start of the free block "bp" and * split that block if the remainder would be at least the minimum block * size. */ static void place(void *bp, size_t asize) { size_t csize = GET_SIZE(HDRP(bp)); struct node *nodep = (struct node *) bp; struct node *new_nodep; /* increased size to account for next and previous pointer overhead */ if ((csize - asize) >= (ASIZE + QSIZE)) { PUT(HDRP(bp), PACK(asize, 1)); PUT(FTRP(bp), PACK(asize, 1)); bp = NEXT_BLKP(bp); PUT(HDRP(bp), PACK(csize - asize, 0)); PUT(FTRP(bp), PACK(csize - asize, 0)); /* Set new node for the leftover free block */ new_nodep = (struct node *)bp; new_nodep->previous = nodep->previous; new_nodep->next = nodep->next; /* Remove node from allocated block */ splice(nodep); } else { PUT(HDRP(bp), PACK(csize, 1)); PUT(FTRP(bp), PACK(csize, 1)); /* Remove node from allocated block */ splice(nodep); } checkheap(1); }
inline static void* find_fit(size_t asize) { #else static void* find_fit(size_t asize) { #endif int free_list_num = 0; void *bp = NULL; free_list_num = get_nonempty_list_num(asize); dbg1("[IN ] : find_fit()\n"); dbg1(" class? [%d]\n", free_list_num); /* find block that fits starting at appropriate free list */ for(bp = GET_FREE_LISTP(free_list_num); bp != NULL; bp = NEXT_FREE_BLKP(bp)) { if(GET_SIZE(HDRP(bp)) >= asize) { dbg1("[OUT] : find_fit() : found block in the first non-empty list\n"); return bp; } } /* if no class bigger than current class exists */ if(free_list_num >= MAXCLASS) { dbg1("[OUT] : find_fit() : failed to find fit, should extend the heap\n"); return NULL; } /* return next class' first free block (if its empty it will contain NULL) */ bp = GET_FREE_LISTP(free_list_num+1); checkheap(); dbg1("[OUT] : find_fit() : failed to find fit, try next free list\n"); return bp; }
//Coalesce free blocks if possible static void *coalesce(void *bp) { size_t prev_alloc = block_free(block_prev(get_header(bp))); size_t next_alloc = block_free(block_next(get_header(bp))); size_t size = block_size(get_header(bp)); if(prev_alloc && next_alloc) return bp; else if(prev_alloc && !next_alloc) { size += block_size(block_next(get_header(bp))); PUT(get_header(bp), PACK(size, 0)); PUT(get_footer(bp), PACK(size, 0)); } else if(!prev_alloc && next_alloc) { size += block_size(block_prev(get_header(bp))); PUT(get_header(prev_bp(bp)), PACK(size, 0)); PUT(get_footer(bp), PACK(size, 0)); bp = prev_bp(bp); } else if(!prev_alloc && !next_alloc) { size += block_size(block_next(get_header(bp))) + block_size(block_prev(get_header(bp))); PUT(get_header(prev_bp(bp)), PACK(size, 0)); PUT(get_footer(next_bp(bp)), PACK(size, 0)); bp = prev_bp(bp); } checkheap(1); return bp; }
/* * realloc - you may want to look at mm-naive.c */ void* realloc(void *oldptr, size_t size) { size_t oldsize; void *newptr; /* If size == 0 then this is just free, and we return NULL. */ if(size == 0) { free(oldptr); return NULL; } /* If oldptr is NULL, then this is just malloc. */ if(oldptr == NULL) { return malloc(size); } newptr = malloc(size); /* If realloc() fails the original block is left untouched */ if(newptr == NULL) { return NULL; } /* Copy the old data. */ oldsize = block_size(block_from_ptr(oldptr)); oldsize = oldsize - (HEADER_SIZE + FOOTER_SIZE); if(size < oldsize) oldsize = size; newptr = memmove(newptr, oldptr, oldsize); /* Free the old block. */ free(oldptr); checkheap(1); return newptr; }
/* * calloc - you may want to look at mm-naive.c */ void* calloc (size_t nmemb, size_t size) { size_t bytes = nmemb * size; void *ptr; ptr = malloc(bytes); memset(ptr, 0, bytes); checkheap(1); return ptr; }
/* * Requires: * "bp" is the address of a newly freed block. * * Effects: * Perform boundary tag coalescing. Returns the address of the coalesced * block. */ static void * coalesce(void *bp) { printf("Start coalesce\n"); if (bp == NULL) printf("Pointer is NULL\n"); struct node *new_node; size_t size = GET_SIZE(HDRP(bp)); printf("Got size\n"); bool prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); printf("Stored whether previous block was allocated\n"); bool next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); printf("Stored whether the next block was allocated\n"); printf("Finished coalesce initializations\n"); if (prev_alloc && next_alloc) { /* Case 1 */ printf("Case 1\n"); return (bp); } else if (prev_alloc && !next_alloc) { /* Case 2 */ printf("Case 2\n"); size += GET_SIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); splice((struct node *)NEXT_BLKP(bp)); } else if (!prev_alloc && next_alloc) { /* Case 3 */ printf("Case 3\n"); size += GET_SIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); /* Seems to work for now, but rather hackish */ /* the issue arises because bp is not actually in the list yet (I think) */ struct node *temp = (struct node *)bp; if (temp->next != NULL) splice(bp); bp = PREV_BLKP((void *)bp); } else { /* Case 4 */ printf("Case 4\n"); size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); splice((struct node *)bp); splice((struct node *)NEXT_BLKP(bp)); bp = PREV_BLKP(bp); } new_node = (struct node *)coalesce(bp); new_node->next = list_start; new_node->previous = NULL; list_start->previous = new_node; list_start = new_node; checkheap(1); return (bp); }
/* * Requires: * words: the number of words to increase the heap by * next: next pointer at the end of the linked list, to be set to the header of the new block * Effects: * Extend the heap with a free block and return that block's address. */ static void * extend_heap(size_t words) { size_t size; void *bp; /* Allocate an even number of words to maintain alignment. */ size = (words % 2) ? (words + 1) * WSIZE : words * WSIZE; if ((bp = mem_sbrk(size)) == (void *)-1) return (NULL); printf("Before extended block is added to the free list\n"); checkheap(1); /* Initialize the new node pointers, next precedes previous */ /* The previous point points to the header of the previous block*/ /*PUT(bp, NULL); PUT(bp + WSIZE, HDRP(next));*/ /* Initialize free block header/footer and the epilogue header. */ PUT(HDRP(bp), PACK(size, 0)); /* Free block header */ PUT(FTRP(bp), PACK(size, 0)); /* Free block footer */ PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* New epilogue header */ /* If list start is NULL, initialize the start to the pointer to the * added block */ if (list_start == NULL) { list_start = (struct node *)bp; list_start->next = list_start; list_start->previous = list_start; } printf("For isolation\n"); add_to_front(bp); printf("After extended block is added to the free list\n"); checkheap(1); printf("Entering coalesce from extend_heap\n"); /* Coalesce if the previous block was free. */ return (coalesce(bp)); }
/* * malloc */ void *malloc (size_t size) { checkheap(1); // Let's make sure the heap is ok! unsigned int awords; //Adjusted block size unsigned int ewords; //Amount to extend heap if no matching uint32_t *block; uint32_t * heap_lastp = last_block(); if (VERBOSE) printf("Malloc %d bytes\n", (int)size); /* Ignore 0 requests */ if (size == 0) return NULL; /* Adjust size to include alignment and convert to multipes of 4 bytes */ if (size <= DSIZE) awords = 2; else awords = (((size) + (DSIZE-1)) & ~0x7) / WSIZE; /* Search the free list for a fit */ if ((block = find_fit(awords)) != NULL) { place(block, awords); //printf("3\n"); return block_mem(block); } /* No fit found. Get more memory and place the block */ if (awords > CHUNKSIZE) ewords = awords; else if (0) ewords = awords; else ewords = CHUNKSIZE; if (block_free(heap_lastp)) { ENSURES(block_size(heap_lastp) < ewords); ewords = ewords - block_size(heap_lastp) + 2; //ewords += 2; //printf("1\n"); } else { ewords += 2; // ask for 2 more for the header and footer //printf("2\n"); } if ((block = extend_heap(ewords)) == NULL) return NULL; place(block, awords); return block_mem(block); }
/* * malloc */ void *malloc (size_t size) { void* p; int index; if(heap_start == 0) mm_init(); checkheap(1); // Let's make sure the heap is ok! if(size == 0) return NULL; size += 8 - size%8; size += (HEADER_SIZE + FOOTER_SIZE); if(size > MAX_SIZE) return NULL; index = get_free_list_index(size); p = find_free_block(index, size); if(p == NULL) return NULL; p = block_mem(p); checkheap(1); return p; }
/* * free */ void free (void *ptr) { size_t size; void* block; int index; checkheap(1); if (ptr == NULL) { return; } if(heap_start == 0) mm_init(); block = block_from_ptr(ptr); index = coalesce(block, &size); block_mark(block, 1); //set_prev_pointer(block, NULL); //set_next_pointer(block, NULL); add_block_to_list(index, block); checkheap(1); return; }
void printblock(void *bp) { size_t hsize, halloc, fsize, falloc; checkheap(0); hsize = GET_SIZE(HDRP(bp)); halloc = GET_ALLOC(HDRP(bp)); fsize = GET_SIZE(FTRP(bp)); falloc = GET_ALLOC(FTRP(bp)); if (hsize == 0) { printf("%p: EOL\n", bp); return; } }
static void printblock(void *bp) { size_t hsize/*, halloc, fsize, falloc*/; checkheap(0); hsize = GET_SIZE(HDRP(bp)); //halloc = GET_ALLOC(HDRP(bp)); //fsize = GET_SIZE(FTRP(bp)); //falloc = GET_ALLOC(FTRP(bp)); if (hsize == 0) { printf("%p: EOL\n", bp); return; } /* printf("%p: header: [%p:%c] footer: [%p:%c]\n", bp, hsize, (halloc ? 'a' : 'f'), fsize, (falloc ? 'a' : 'f')); */ }
/* * Requires: * "bp" is either the address of an allocated block or NULL. * * Effects: * Free a block. */ void mm_free(void *bp) { size_t size; /* Ignore spurious requests. */ if (bp == NULL) return; /* Free and coalesce the block. */ size = GET_SIZE(HDRP(bp)); /* Reset Header and Footer to be free */ PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); coalesce(bp); checkheap(1); }
/* * Requires: * "bp" is the address of a block. * * Effects: * Print the block "bp". */ static void printblock(void *bp) { bool halloc, falloc; size_t hsize, fsize; checkheap(false); hsize = GET_SIZE(HDRP(bp)); halloc = GET_ALLOC(HDRP(bp)); fsize = GET_SIZE(FTRP(bp)); falloc = GET_ALLOC(FTRP(bp)); if (hsize == 0) { printf("%p: end of heap\n", bp); return; } printf("%p: header: [%zu:%c] footer: [%zu:%c]\n", bp, hsize, (halloc ? 'a' : 'f'), fsize, (falloc ? 'a' : 'f')); }
static int skew_retrieve (lua_State *L) { /* delete */ heap *h = checkheap(L, 1); heap *h3; /* output heap */ heap *y1, *y2; /* current nodes on the major and minor paths */ heap *x; /* next node to be added to the output heap */ lua_settop(L, 1); if (h == NULL) { lua_pushnil(L); lua_pushnil(L); return 3; } y1 = h->up; y2 = h->down; if (y1->value < y2->value) { x = y1; y1 = y2; y2 = x; /* y1 <-> y2 */ } if (y1 == h) { pushheap(L, NULL); /* h = NULL */ pushvaluekey(L, y1); delheap(L, h); return 3; } /* initialize h3 to hold y1 */ h3 = y1; y1 = y1->up; h3->up = h3; while (1) { if (y1->value < y2->value) { x = y1; y1 = y2; y2 = x; /* y1 <-> y2 */ } if (y1 == h) { pushheap(L, h3); /* h = h3 */ pushvaluekey(L, y1); delheap(L, h); return 3; } /* remove x == y1 from its path */ x = y1; y1 = y1->up; /* add x to the top of h3 and swap its children */ x->up = x->down; x->down = h3->up; h3->up = x; h3 = h3->up; } }
/** * coalesce - Coalesce the blocks to avoid fragmentation. * Need to be done after every block free. * @param bp Block pointer to block to be coalesced */ static inline void *coalesce_block(void *bp) { size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp))); size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GET_SIZE(HDRP(bp)); /*The line kept, so that compiler dont complain.*/ if(size == 0) { checkheap(9); } if ( prev_alloc && next_alloc ) { /* Case 1 */ return bp; } else if ( prev_alloc && !next_alloc ) { /* Case 2 */ size += GET_SIZE( HDRP( NEXT_BLKP( bp ))); /* Next is not allocated-- remove from free list */ delete_free_list( NEXT_BLKP( bp )); PUT( HDRP( bp ), PACK( size, 0 )); PUT( FTRP( bp ), PACK( size, 0 )); } else if ( !prev_alloc && next_alloc ) { /* Case 3 */ bp = PREV_BLKP(bp); size += GET_SIZE(HDRP(bp)); /* Previous is not allocated-- remove from free list */ delete_free_list(bp); PUT(HDRP(bp), PACK(size,0)); PUT(FTRP(bp), PACK(size,0)); } else { /* Case 4 */ /* Both Previous and Next Block are not allocated */ size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(FTRP(NEXT_BLKP(bp))); /* Remove both previous and next */ delete_free_list(PREV_BLKP(bp)); delete_free_list(NEXT_BLKP(bp)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); } return bp; }
/* * malloc */ void *malloc (size_t size) { checkheap(1); // Let's make sure the heap is ok! size = size; size_t asize; /* Adjusted block size */ size_t extendsize; /* Amount to extend heap if no fit */ char *bp; /* $end mmmalloc */ if (heap_listp == 0){ mm_init(); } /* $begin mmmalloc */ /* Ignore spurious requests */ if (size == 0) return NULL; /* Adjust block size to include overhead and alignment reqs. */ if (size <= DSIZE) //line:vm:mm:sizeadjust1 asize = 2*DSIZE; //line:vm:mm:sizeadjust2 else asize = DSIZE * ((size + (DSIZE) + (DSIZE-1)) / DSIZE); //line:vm:mm:sizeadjust3 /* Search the free list for a fit */ if ((bp = find_fit(asize)) != NULL) { //line:vm:mm:findfitcall place(bp, asize); //line:vm:mm:findfitplace return (void *)bp; } /* No fit found. Get more memory and place the block */ extendsize = MAX(asize,CHUNKSIZE); //line:vm:mm:growheap1 if ((bp = extend_heap(extendsize/WSIZE)) == NULL) return NULL; //line:vm:mm:growheap2 place(bp, asize); //line:vm:mm:growheap3 return (void *)bp; }
/* * Requires: * None. * * Effects: * Allocate a block with at least "size" bytes of payload, unless "size" is * zero. Returns the address of this block if the allocation was successful * and NULL otherwise. */ void * mm_malloc(size_t size) { size_t asize; /* Adjusted block size */ size_t extendsize; /* Amount to extend heap if no fit */ void *bp; printf("Start malloc\n"); /* Ignore spurious requests. */ if (size == 0) return (NULL); /* Adjust block size to include overhead and alignment reqs. */ /* Increased size to 4 words of overhead from 2 */ /* Smallest useable block size is now 2 words instead of 1 */ if (size <= ASIZE) asize = ASIZE + QSIZE; else asize = ASIZE * ((size + QSIZE + (ASIZE - 1)) / ASIZE); /* Search the free list for a fit. */ if ((bp = find_fit(asize)) != NULL) { place(bp, asize); return (bp); } /* No fit found. Get more memory and place the block. */ extendsize = MAX(asize, CHUNKSIZE); if ((bp = extend_heap(extendsize / WSIZE)) == NULL) return (NULL); place(bp, asize); checkheap(1); return (bp); }
/* * malloc */ void *malloc (size_t size) { checkheap(1); // Let's make sure the heap is ok! size = size; return NULL; }
static int skew_min (lua_State *L) { pushvaluekey(L, checkheap(L, 1)); return 2; }
/** * mm_checkheap - Function, to call checkheap as per verbose value * @param verbose value determines what things to print in checkheap */ void mm_checkheap(int verbose) { /*Get gcc to be quiet. */ verbose = verbose; checkheap(verbose); }
inline static size_t get_list_num(size_t size) { #else static size_t get_list_num(size_t size) { #endif if(size <= BLKSIZE) return 0; if(size <= (BLKSIZE << 1)) return 1; if(size <= (BLKSIZE << 2)) return 2; if(size <= (BLKSIZE << 3)) return 3; if(size <= (BLKSIZE << 4)) return 4; if(size <= (BLKSIZE << 5)) return 5; if(size <= (BLKSIZE << 6)) return 6; if(size <= (BLKSIZE << 7)) return 7; return 8; } #endif #ifdef CLASS1 #ifdef INLINE inline static size_t get_nonempty_list_num(size_t size) { #else static size_t get_nonempty_list_num(size_t size) { #endif dbg1("[IN ] : get_nonempty_list_num():request[%ld] - class1\n", size); if(size <= BLKSIZE && GET_FREE_LISTP(0) != NULL) return 0; if((size <= 40) && GET_FREE_LISTP(1) != NULL) return 1; if((size <= 48) && GET_FREE_LISTP(2) != NULL) return 2; if((size <= 56) && GET_FREE_LISTP(3) != NULL) return 3; if(size <= (BLKSIZE << 1) && GET_FREE_LISTP(4) != NULL) return 4; if(size <= (BLKSIZE << 2) && GET_FREE_LISTP(5) != NULL) return 5; if(size <= (BLKSIZE << 3) && GET_FREE_LISTP(6) != NULL) return 6; if(size <= (BLKSIZE << 4) && GET_FREE_LISTP(7) != NULL) return 7; if(size <= (BLKSIZE << 5) && GET_FREE_LISTP(8) != NULL) return 8; if(size <= (BLKSIZE << 6) && GET_FREE_LISTP(9) != NULL) return 9; if(size <= (BLKSIZE << 7) && GET_FREE_LISTP(10) != NULL) return 10; return 11; } #ifdef INLINE inline static size_t get_list_num(size_t size) { #else static size_t get_list_num(size_t size) { #endif if(size <= BLKSIZE) return 0; if(size <= 40) return 1; if(size <= 48) return 2; if(size <= 56) return 3; if(size <= (BLKSIZE << 1)) return 4; if(size <= (BLKSIZE << 2)) return 5; if(size <= (BLKSIZE << 3)) return 6; if(size <= (BLKSIZE << 4)) return 7; if(size <= (BLKSIZE << 5)) return 8; if(size <= (BLKSIZE << 6)) return 9; if(size <= (BLKSIZE << 7)) return 10; return 11; } #endif /* debugging routines */ /* * mm_checkheap - called by mdriver for each operation in the trace file * */ void mm_checkheap(int v) { verbose = v; checkheap(); } #ifdef CHECKHEAP static void printblock(void *bp) { size_t hsize, halloc, hpalloc, fsize, falloc, fpalloc; hsize = GET_SIZE(HDRP(bp)); halloc = GET_ALLOC(HDRP(bp)); hpalloc = GET_PREV_ALLOC(HDRP(bp)); fsize = GET_SIZE(FTRP(bp)); falloc = GET_ALLOC(FTRP(bp)); fpalloc = GET_PREV_ALLOC(HDRP(bp)); if (hsize == 0) { printf("%p: EOL (size=0): header: [%ld:%c:%c]\n", bp, hsize, (hpalloc ? 'a' : 'f'), (halloc ? 'a' : 'f')); return; } printf("%p: header: [%ld:%c:%c] footer: [%ld:%c:%c]\n", bp, hsize, (hpalloc ? 'a' : 'f'), (halloc ? 'a' : 'f'), fsize, (fpalloc ? 'a' : 'f'), (falloc ? 'a' : 'f')); }
/* * malloc - allocates a block with requested size * (implementation issue: adjust size, extend size) * */ void *malloc(size_t size) { size_t asize = 0; size_t extendsize; char* bp; #ifdef TWEAK int k; #endif dbg1("[IN ] : malloc() - malloc(%ld)\n", size); checkheap(); if (!mm_initialized) mm_init(); /* Ignore spurious requests */ if (size <= 0) return NULL; #ifdef TWEAK /* * [Optimization for binary*.rep trace files] * if requested size is larger than 2^4=16 bytes, and close to power of two * (when the difference between requested size and its closest larger power of two * is smaller than one eighth of closest power of two) round up to power of two */ k = ceil_log_2(size); if( k >= 4 && ((1 << k) - size) <= (unsigned)(1 << (k -3))) { size = 1 << k; } dbg1("intermediate size : %ld\n", size); #endif #ifdef PUTBUG if (size <= MINBLKSIZE) { asize = MINBLKSIZE + WSIZE; } else { asize = DSIZE * ((size + DSIZE-1)/DSIZE); } #endif #ifdef ASIZE1 /* Adjust block size to include overhead and alignment reqs */ /* Block should at least have space for Header, Footer, Pred, Succ Pointers */ if (size <= MINBLKSIZE) { asize = MINBLKSIZE + WSIZE; } else { asize = DSIZE * ((size + WSIZE + DSIZE-1)/DSIZE); } #endif #ifdef ASIZE2 if (size <= 2*DSIZE+OVERHEAD) { asize = 2*DSIZE+OVERHEAD+OVERHEAD; } else { /* round up to the nearest order of 16 */ asize = 2*DSIZE * ((size + (OVERHEAD - WSIZE) + 2*DSIZE-1)/(2*DSIZE)); } #endif #ifdef ASIZE3 if (size <= DDSIZE){ asize = DDSIZE + DSIZE; } else { asize = DDSIZE*((size + (DSIZE - WSIZE) + (DDSIZE-1)) / DDSIZE); } #endif dbg("malloc: adjusted size %ld, class %ld\n", asize, get_list_num(asize)); /* Search the free list for a fit */ if ((bp = find_fit(asize)) != NULL) { place(bp, asize); dbg1("[OUT] : malloc() - found fit\n"); return bp; } /* No fit found. Get more memory and place the block */ extendsize = MAX(asize, CHUNKSIZE); if((bp = extend_heap(extendsize/WSIZE)) == NULL) return NULL; place(bp, asize); dbg1("[OUT] : malloc() - found fit failed, extended the heap\n"); return bp; }
/* * mm_checkheap * 检查heap的正确性,一直在silent的运行,知道有错误出现就print * int lineno? * original!! */ void mm_checkheap(int verbose) { verbose = verbose; checkheap(verbose); }