Beispiel #1
0
/*
** Merge as possible the next block or/and
** the previous block with the current parameter.
** Return the new address of the current block.
*/
t_ptr		heap_merge(t_ptr block)
{
  size_t	size;
  size_t	prev_state;
  size_t	next_state;

  assert(!IS_B_ALLOC(block));
  size = GET_B_SIZE(block);
  prev_state = IS_B_ALLOC(GET_PREV(block));
  next_state = IS_B_ALLOC(GET_NEXT(block));
  if (!prev_state)
    {
      size += GET_B_SIZE(GET_PREV(block));
      if (!next_state)
	size += GET_B_SIZE(GET_NEXT(block));
      SET(GET_HEAD(GET_PREV(block)), PACK(size, 0));
      SET(GET_FOOT(GET_PREV(block)), PACK(size, 0));
      block = GET_PREV(block);
    }
  else if (!next_state)
    {
      size += GET_B_SIZE(GET_NEXT(block));
      SET(GET_HEAD(block), PACK(size, 0));
      SET(GET_FOOT(block), PACK(size, 0));
    }
  return (block);
}
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
/* remove an element from the freelist */
void fl_remove(void* ptr)
{
  void** freelist = (void**)(master->ptr+WSIZE);
  unsigned int size = GETSIZE(ptr);
  int idx = log_two(size) - 4;
  /*
  void* curr = freelist[idx];
  void* prev = NULL;
  while ((curr- ptr)!=0 && (curr != NULL))
  {
 	prev = curr;
	curr = GET_NEXT(curr);
  }
  */

  //if (curr == NULL) return; //shouldn't really happen
  
  if (GET_NEXT(ptr) != NULL) PUT_PREV(GET_NEXT(ptr),GET_PREV(ptr));

  if (GET_PREV(ptr) == NULL) //ptr is the first element 
  { 
	freelist[idx] = GET_NEXT(ptr);
  } else {
        PUT_NEXT(GET_PREV(ptr), GET_NEXT(ptr));
  }
  //return;
}
Beispiel #4
0
int validFreeList(char *bp)
{
#ifdef DEBUG
  char *hdr ;
  int prevOffset ;
  // int offset = (int)(((long)(HDRP(firstFBP))) - (long)(heapStart)) ;
  // offset between first block and heap start
  char * curr = firstFBP ;
  if(curr == NULL) return 1 ;
  //int nextOffset = DEREF_NEXT(curr) ;
  while(curr != heapStart) //curr == heapStart if next field is NULL/0
    {
      hdr = HDRP(curr) ;
      if(GETALLOC(hdr)) return 0 ; // block is not free 
      if(!isValidBlock(curr)) return 0 ;
      prevOffset = DEREF_PREV(curr) ;
      if((prevOffset != 0 && GETALLOC(HDRP(GET_PREV(curr)))) || 
	 (DEREF_NEXT(curr) != 0 && GETALLOC(HDRP(GET_NEXT(curr)))))
	{ // if prev or next is not free
	  return 0 ;
	}
      ASSERT((GET_NEXT(curr)==heapStart) || GET_PREV(GET_NEXT(curr)) == curr)  ;
   
      curr = GET_NEXT(curr) ;
      // dbg_printf("Curr->next  = %d \n", DEREF_NEXT(curr)) ; 
      // nextOffset =  DEREF_NEXT(curr) ;
      //no effect if curr == heapStart
    }
  return 1 ;
#else
  return 1 ;
#endif
}
Beispiel #5
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 #6
0
static buddy_block_t *buddy_remove_free(buddy_ctxt_t *buddy, int index, int order)
{
    buddy_block_t *block = buddy->all + index;
    int index_next = GET_NEXT(block);
    int index_prev = GET_PREV(block);

    buddy_block_t *next = buddy->all + index_next;
    buddy_block_t *prev = buddy->all + index_prev;

    /* adjust next/prev index + free list */
    if(index_prev == index) {
        if(index_next == index) {
            buddy->free[order] = -1;
        } else {
            buddy->free[order] = index_next;
            next->prev = (next->prev & MASK_ORDER) | index_next;
        }
    } else {
        if(index_next == index) {
            prev->next = (prev->next & MASK_ORDER) | index_prev;
        } else {
            next->prev = (next->prev & MASK_ORDER) | index_prev;
            prev->next = (prev->next & MASK_ORDER) | index_next;
        }
    }
    return block;
}
Beispiel #7
0
void buddy_dump(buddy_ctxt_t *buddy)
{
    int i;
    printf("  <BUDDY BASE=%x MAX=%d ORDER=%d>\n", buddy->base, buddy->index_max, buddy->order);

    for(i = 0; i < buddy->order; i++) {
        int next, index = buddy->free[i];

        if(index != -1) {
            printf("    <ORDER %d>\n", i);
            for(;;) {
                buddy_block_t *block = buddy->all + index;

                if(index < 0 || index >= buddy->index_max) {
                    printf("      <BLOCK *** ERROR index=%d ***>", index);
                } else {
                    addr_t start = buddy->base + (index<< buddy->page_bits);
                    addr_t end   = start + (1UL << (GET_ORDER(block) + buddy->page_bits));

                    printf("      <BLOCK %s A=%x-%x ORDER=%d ME=%d NEXT=%d PREV=%d>\n",
                           IS_FREE(block) ? "free" : "in use",
                           start, end,
                           GET_ORDER(block),
                           index, GET_NEXT(block), GET_PREV(block)
                          );
                }
                next = GET_NEXT(block);
                if(index == next) break;
                index = next;
            }
        }
    }
}
Beispiel #8
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 ;  
}
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
static void *coalesce(void *bp)
{	
	size_t size = GET_SIZE(bp);

	size_t prev_alloc = GET_PRE_ALLOC_INFO(bp);
	
	size_t next_alloc = GET_ALLOC( GET_NEXT(bp) );
	
	if ( prev_alloc && next_alloc ){ /* Case 0 */
        return bp;
	} else if ( !prev_alloc && next_alloc ) { /* Case 1*/
	    void * prev = (void *)GET_PREV(bp);
	    size_t sign = 0 | GET_PRE_ALLOC_INFO(prev) | GET_PRE_8_INFO(prev);
	    delete_node(prev);
		size += GET_SIZE( prev );
		PUT_HDRP( prev, PACK(size, sign) );
		PUT_FTRP( prev, PACK(size, sign) );
		return prev;
	} else if ( prev_alloc && !next_alloc ) { /* Case 2 */
	    size += GET_SIZE( GET_NEXT(bp) );
	    delete_node( GET_NEXT(bp) );
		size_t sign = 0 | GET_PRE_ALLOC_INFO(bp) | GET_PRE_8_INFO(bp);
		PUT_HDRP( bp, PACK(size,sign) );
		PUT_FTRP( bp, PACK(size,sign) );
		return bp;
	} else { /* Case 3 */
	    void * prev = (void *)GET_PREV(bp);
	    void * next = (void *)GET_NEXT(bp);
	    size += GET_SIZE( prev ) + GET_SIZE( next );
	    
		delete_node( prev );
		delete_node( next );
		
		size_t sign = 0 | GET_PRE_ALLOC_INFO(bp) | GET_PRE_8_INFO(bp);
        PUT_HDRP( prev, PACK(size,sign) );
		PUT_FTRP( prev, PACK(size,sign) );
		return prev;
	}
}
Beispiel #11
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 #12
0
/*
 * mm_checkheap
 */
void mm_checkheap(int lineno) {
	
	void *bp = heap_listp;
	int last_free = 0;
	int count = 0; //how many free blocks
	
	/* check prologue */
	if (GET(bp) != PACK(DSIZE, 1)){
		printf("wrong prologue, at line: %d\n",lineno);
	}
	
	while (1){
		if (GET_SIZE(bp) == 0 && GET_ALLOC(bp) == 1){
			/* reach epilogue */
			if (bp-1 != mem_heap_hi()){
				printf("wrong epilogue,%d\n",lineno);
			}
			break;
		}else{
			/* check aligned */
			if (!aligned(bp)){
				printf("not aligned, at line: %d!\n", lineno);
			}
			/* check ftr == hdr */
			if (GET(HDRP(bp)) != GET(FTRP(bp))){
				printf("hdr != ftr, at line: %d!\n", lineno);
			}
			/* check no consecutive free block */
			if (last_free && GET_ALLOC(bp) == 0){
				printf("consecutive free blocks, at line: %d!\n", lineno);
			}
			last_free = !GET_ALLOC(bp);
			count += last_free;
			bp = NEXT_BLKP(bp);
		}
	}
	
	/* check blocks in explicit free list are all free */
	bp = free_listp;
	while(1){
		bp = GET_NEXT(bp);
		/* check if reach end */
		if (GET_NEXT(bp) == 0){
			break;
		}else{
			/* check free */
			if (GET_ALLOC(bp)){
				printf("allocated block in free list! at line: %d!\n", lineno);
			}
			/* check cur.next.prev == cur and cur.prev.next == cur */
			if (GET_PREV(GET_NEXT(bp)) != bp || GET_NEXT(GET_PREV(bp)) != bp){
				printf("inconsistent pointers! at line: %d!\n", lineno);
			}
			if (!in_heap(bp)){
				printf("not in heap! at line: %d\n", lineno);
			}
			count--;
		}
	}
	/* check free block numbers are the same through two traversing methods */
	if (count){
		printf("inconsistent free block numbers in two checks!, at line: %d\n", lineno);
	}
}