static void FL_insert(char *bp) //insert at start of free list { ASSERT(bp != NULL) ; ASSERT(GETALLOC(HDRP(bp)) == 0) ; ASSERT(isValidBlock(bp)) ; if(firstFBP == NULL) { // free list is empty firstFBP = bp ; SET_PREV(bp, 0) ; SET_NEXT(bp, 0) ; return ; } else { unsigned int offset = firstFBP - heapStart ; SET_NEXT(bp, offset) ; //bp->next = firstFBP offset = (unsigned int)(bp - heapStart) ; // ASSERT(DEREF_PREV(firstFBP) == 0) ; SET_PREV(firstFBP, offset) ; // firstFBP->prev = bp //ASSERT(DEREF_PREV(firstFBP) == offset) ; SET_PREV(bp, 0) ; //bp->prev = NULL firstFBP = bp ; //set bp as start of list return ; } return ; }
/* * place block */ void *place(void *bp, size_t size){ void *free_bp; size_t full_size = GET_SIZE(bp); //size of the free block before place /* not split the free block for small allocation or small space left */ if ((full_size - size) < FSIZE || size < FSIZE ){ /* reset hdr/ftr the alloc bit */ PUT(HDRP(bp), PACK(full_size, 1)); PUT(FTRP(bp), PACK(full_size, 1)); /* delete from free list */ SET_NEXT(GET_PREV(bp), GET_NEXT(bp)); SET_PREV(GET_NEXT(bp), GET_PREV(bp)); return bp; } /* after alloc size bytes, * the original free block still have bytes in the tail, * split the free block into two parts: |alloc one|free one| */ free_bp = bp + size; /* reset ftr/hdr of the new free block*/ PUT(HDRP(free_bp), PACK(full_size-size, 0)); PUT(FTRP(free_bp), PACK(full_size-size, 0)); /* add it to free list, also delete the original free block from list */ SET_NEXT(free_bp, GET_NEXT(bp)); SET_PREV(free_bp, GET_PREV(bp)); SET_NEXT(GET_PREV(bp), free_bp); SET_PREV(GET_NEXT(bp), free_bp); /* set hdr/ftr of alloc block */ PUT(HDRP(bp), PACK(size, 1)); PUT(FTRP(bp), PACK(size, 1)); return bp; }
static void FL_remove(char *bp) //remove block from free list given free block bp { ASSERT(bp != NULL) ; ASSERT(GETALLOC(bp) == 0) ; ASSERT(bp != epilogue && bp != prologue && bp != heapStart) ; if(bp == NULL) return ; else if(DEREF_NEXT(bp) == 0 && DEREF_PREV(bp) == 0) { // if list has only 1 element make list empty firstFBP = NULL ; return ; } char *next_bp = GET_NEXT(bp) ; char *prev_bp = GET_PREV(bp) ; if(next_bp == heapStart && prev_bp == heapStart) { firstFBP = NULL ; // empty free list return ; } else if(next_bp == heapStart) { //prev_bp != heapStart SET_NEXT(prev_bp, 0) ; //if bp is end node in free list next->prev = 0 return ; } else if (prev_bp == heapStart) { SET_PREV(next_bp, 0) ; // if bp is start node, next->prev = 0 firstFBP = next_bp ; // change firstFBP to point to new bp ASSERT(DEREF_PREV(firstFBP) == 0) ; return ; } // normal case SET_PREV(next_bp, DEREF_PREV(bp)) ; SET_NEXT(prev_bp, DEREF_NEXT(bp)) ; // prev->next = curr->next return ; }
/* * realloc * if realloc size is larger than old one: malloc new space and copy * if realloc size is smaller: shrink the block, * and release the space as a free block */ void *realloc(void *oldptr, size_t size) { size_t asize; size_t oldsize; void *newptr; void *free_bp; /* If size == 0 then this is just free, and we return NULL. */ if(size == 0) { free(oldptr); return 0; } /* If oldptr is NULL, then this is just malloc. */ if(oldptr == NULL) { return malloc(size); } asize = ALIGN(size + 2*WSIZE); oldsize = GET_SIZE(oldptr); if (oldsize < asize){ /* if realloc size is larger than old one: malloc new space and copy*/ newptr = malloc(size); memcpy(newptr, oldptr, oldsize - 2*WSIZE); free(oldptr); return newptr; }else if (oldsize > asize){ /* realloc a smaller space */ if ((oldsize - asize) < FSIZE || asize < FSIZE ){ /* no changes */ return oldptr; }else{ free_bp = oldptr + asize; /* set alloc bit to 0*/ PUT(HDRP(free_bp), PACK(oldsize-asize, 0)); PUT(FTRP(free_bp), PACK(oldsize-asize, 0)); /* add to free list */ SET_NEXT(free_bp, GET_NEXT(free_listp)); SET_PREV(free_bp, free_listp); SET_NEXT(free_listp, free_bp); SET_PREV(GET_NEXT(free_bp), free_bp); /* change the alloced block size to new size*/ PUT(HDRP(oldptr), PACK(asize, 1)); PUT(FTRP(oldptr), PACK(asize, 1)); return oldptr; } }else{ /* same size, no changes */ return oldptr; } }
/* * free * free a block and add it the the free list, then coalesce */ void free (void *ptr) { size_t size; if (ptr == NULL)return; size = GET_SIZE(ptr); /* reset hdr/ftr of alloc bit */ PUT(HDRP(ptr), PACK(size, 0)); PUT(FTRP(ptr), PACK(size, 0)); /* add to free list */ SET_NEXT(ptr, GET_NEXT(free_listp)); SET_PREV(ptr, free_listp); SET_PREV(GET_NEXT(ptr), ptr); SET_NEXT(free_listp, ptr); coalesce(ptr); }
/* remove a link from the list `list' */ extern t_list * removeElementLink(t_list *list, t_list *element) { t_list *current_elem; /* preconditions */ if (list == NULL || element == NULL) return list; if ((LPREV(element) == NULL) && (element != list)) return list; /* intialize the value of `current_elem' */ current_elem = list; while( (LDATA(current_elem) != LDATA(element)) || (LPREV(current_elem) != LPREV(element)) || (LNEXT(current_elem) != LNEXT(element)) ) { /* retrieve the next element from the list */ current_elem = LNEXT(current_elem); /* test if we reached the end of the list */ if (current_elem == NULL) return list; } if (LPREV(element) == NULL) { assert(list == element); if (LNEXT(element) != NULL) { list = LNEXT(element); SET_PREV(LNEXT(element), NULL); } else list = NULL; /* remove the allocated memory of element */ _FREE_FUNCTION(element); return list; } /* we found the element */ if (LPREV(element) != NULL) { /* we found the element, and it is the top of the list */ SET_NEXT(LPREV(element), LNEXT(element)); } if (LNEXT(element) != NULL) SET_PREV(LNEXT(element), LPREV(element)); /* remove the allocated memory of element */ _FREE_FUNCTION(element); /* return the new top of the list */ return list; }
static void add_free(void *bp) { //printf("%d %p %p\n", asize, hp, *hp); if(free_listp) SET_PREV(free_listp, bp); SET_PREV(bp, 0); SET_NEXT(bp, free_listp); free_listp = bp; }
/** * Adds this block to the free list of * free blocks. * @param - bp - pointer to a block that is already marked free. */ static void mm_insert(void *bp){ /* set bp next to listp */ SET_NEXT(bp, listp); /* set prev listp to bp */ SET_PREV(listp, bp); /* set prev bp to NULL */ SET_PREV(bp, NULL); /* set start of list to bp */ listp = bp; }
static void rm_free(void *bp) { //bp->prev->next = bp->next; //bp->next->prev = bp->prev; size_t *prev = GET_PREV(bp); size_t *next = GET_NEXT(bp); if(prev) SET_NEXT(prev, next); else free_listp = next; if(next) SET_PREV(next, prev); }
void LLadd(char *bp) { char *head = free_list; SET_NEXT(bp, head); SET_PREV(bp, NULL); if(head != NULL) { SET_PREV(head, bp); } free_list = bp; }
/** * Removes this block from the list of * free blocks. * @param - bp - pointer to a block that is on the list of free blocks. */ static void mm_remove(void *bp){ /* if prev bp, then set it's next to bp next */ if (PREV_PTR(bp)){ SET_NEXT(PREV_PTR(bp), NEXT_PTR(bp)); } else{ /* set listp to bp's next */ listp = NEXT_PTR(bp); } /* set prev of next after bp to prev of bp */ SET_PREV(NEXT_PTR(bp), PREV_PTR(bp)); }
/* * coalesce next block with current block * this method only called by coalesce, * pre-condistion is bp block is free and its next block in heap is free too, * so we merge them */ void coalesce_next(void *bp){ size_t size = GET_SIZE(bp); void *next_bp = NEXT_BLKP(bp); /* delete next_bp from free list */ SET_NEXT(GET_PREV(next_bp), GET_NEXT(next_bp)); SET_PREV(GET_NEXT(next_bp), GET_PREV(next_bp)); /* reset hdr/ftr of the new free block */ size += GET_SIZE(NEXT_BLKP(bp)); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size, 0)); }
/* * extend heap * call mem_sbrk to get a free block * put the block into free list */ void *extend_heap(size_t words){ void *bp; size_t size; size = words*WSIZE; if((bp = mem_sbrk(size)) == (void *)-1) return NULL; /* initialize free block hdr/ftr */ PUT(HDRP(bp), PACK(size, 0)); //Free block hdr PUT(FTRP(bp), PACK(size, 0)); //Free block ftr /* put it in the free list */ SET_NEXT(bp, GET_NEXT(free_listp)); SET_PREV(bp, free_listp); SET_NEXT(free_listp, bp); SET_PREV(GET_NEXT(bp), bp); /* re-init epilogue hdr */ PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1)); /* coalesce free blocks */ return coalesce(bp); }
/* remove an element from the list */ t_list * removeElement(t_list *list, void * data) { t_list *current_elem; /* preconditions: the list shouldn't be empty */ if (list == NULL) return NULL; /* intialize the value of `current_elem' */ current_elem = list; while ( (current_elem != NULL) && (LDATA(current_elem) != data)) { current_elem = LNEXT(current_elem); } /* the value hasn't been found */ if (current_elem == NULL) return list; /* the value is found */ if (LPREV(current_elem) != NULL) { SET_NEXT(LPREV(current_elem), LNEXT(current_elem)); if (LNEXT(current_elem) != NULL) SET_PREV(LNEXT(current_elem), LPREV(current_elem)); _FREE_FUNCTION(current_elem); } else { /* check the preconditions */ assert(list == current_elem); if (LNEXT(current_elem) != NULL) { SET_PREV(LNEXT(current_elem), NULL); /* update the new head of the list */ list = LNEXT(current_elem); } else list = NULL; _FREE_FUNCTION(current_elem); } /* postconditions: return the new head of the list */ return list; }
/* add an element at the beginning of the list */ t_list * addFirst(t_list *list, void * data) { t_list *result; /* initialize the value of `result' */ result = newElement(data); if (list == NULL) return result; /* postconditions */ SET_PREV(list, result); SET_NEXT(result, list); /* return the new head of the list */ return result; }
void LLrem(char *bp) { unsigned int next = GET_NEXT(bp); unsigned int prev = GET_PREV(bp); if(prev == 0)// bp is head of list { free_list = (char *) next; if(next != 0) { SET_PREV((char *)next, NULL); } } else { SET_NEXT((char *) prev, next); if(next != 0) { SET_PREV((char *) next, prev); } } }
t_list * newElement(void *data) { t_list * result; /* create an instance of t_list in memory */ result = (t_list *) _ALLOC_FUNCTION(sizeof(t_list)); /* verify the out of memory condition */ if (result == NULL) { fprintf(stderr, "COLLECTIONS.C:: _ALLOC_FUNCTION returned a NULL pointer \n"); abort(); } /* set the internal value of the just created t_list element */ SET_DATA(result, data); SET_PREV(result, NULL); SET_NEXT(result, NULL); /* postconditions : return the element */ return result; }
/* * * mm_init - Initialize the memory manager * */ int mm_init(void) { /* Create the initial empty heap */ if ((heap_listp = mem_sbrk(5*DSIZE)) == (void *)-1) return -1; heap_bot = mem_heap_lo(); PUT(heap_listp, 0); /* Alignment padding */ /* Adds Prologue footer and header */ PUT_HD_FT(heap_listp + (DSIZE), 2*DSIZE, 1); PUT_HD_FT(heap_listp + (3*DSIZE), 2*DSIZE, 1); PUT(heap_listp + (9 *WSIZE), PACK(0,1)); //initialization pointers for explicit list *(int *) (heap_listp + (3*DSIZE)) = -1; SET_NEXT(heap_listp + (3*DSIZE), heap_listp + (DSIZE)); SET_PREV(heap_listp +(DSIZE), heap_listp + (3*DSIZE)); *(int *) (heap_listp + (DSIZE) + WSIZE) = -1; heap_listp += (3*DSIZE); /* Extend the empty heap*/ if(extend_heap(WSIZE + 2) == NULL) return -1; return 0; }
/* add an element `data' to the list `list' at position `pos'. If pos is negative * , or is larger than the number of elements in the list, the new element is * added on to the end of the list. Function `addElement' returns a pointer * to the new head of the list */ t_list * addElement(t_list *list, void * data, int pos) { t_list *result; t_list *current_elem; t_list *last_elem; int current_pos; /* initialize the value of `result' */ result = newElement(data); if (list == NULL) return result; if (pos == 0) { /* update the control informations */ SET_NEXT(result, list); SET_PREV(list, result); /* return the new head of the list */ return result; } /* retrieve the last element of the list */ last_elem = getLastElement(list); assert(last_elem != NULL); if (pos < 0) { /* update the control informations */ SET_NEXT(last_elem, result); SET_PREV(result, last_elem); /* update the value of result */ return list; } /* `pos' is a positive integer */ current_pos = 0; current_elem = list; while(current_pos < pos) { if (current_elem == last_elem) { /* update the control informations */ SET_NEXT(last_elem, result); SET_PREV(result, last_elem); /* update the value of result */ return list; } /* update the loop informations */ current_elem = LNEXT(current_elem); current_pos++; } /* assertions */ assert(current_elem != NULL); /* update the control informations */ SET_NEXT(result, current_elem); SET_PREV(result, LPREV(current_elem)); SET_NEXT(LPREV(current_elem), result); SET_PREV(current_elem, result); /* return the new head of the list */ return list; }