Beispiel #1
0
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 ;
}
Beispiel #2
0
/*
 * 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;
}
Beispiel #3
0
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 ;  
}
Beispiel #4
0
/*
 * 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;
	}
}
Beispiel #5
0
/*
 * 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);
}
Beispiel #6
0
/* 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;
}
Beispiel #8
0
/**
 * 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);
}
Beispiel #10
0
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;
}
Beispiel #11
0
/**
 * 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));
}
Beispiel #12
0
/*
 * 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));
}
Beispiel #13
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);
}
Beispiel #14
0
/* 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;
}
Beispiel #15
0
/* 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;
}
Beispiel #16
0
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);
	}
    }
}
Beispiel #17
0
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;
}
Beispiel #18
0
/* 
 *  * 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;
}
Beispiel #19
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;
}