Пример #1
0
/*
 * mm_check - check basic heap consistency.
 *
 *	Check 1 : Is every block in the free list marked as free?
 *  Check 2 : Are there any contiguous free blocks that somehow escaped coalescing?
 *  Check 3 : Is every free block except 8byte actually in the free list?
 *
 */
int mm_check()
{
	int flag = 0;
	
	//printf("Heap Consistency Checker : starts checking\n");
	
	// Check 1 : Is every block in the free list marked as free?
	// 1-1 Checking for 16-list
	FREE prev = NULL;
	FREE iter = address_list;
	
	while(iter)
	{
		if(!checkMarkedAsFree(iter))
		{
			
			printf("Heap Consistency Checker : %x is not marked as free though it's in free-list(16Byte)\n", (size_t)iter);
			int size = FSIZE(iter);
			printf("Heap Consistency Checker : Value of Header = %x, Value of Footer = %x\n", *(size_t*)iter, *(size_t*)((char *)iter+size-HEADER_SIZE));
			flag=1;
		}
		iter=right(iter);
	}
	
	// 1-2 Checking for tree
	flag=flag|checkTreeMakredAsFree(address_tree);
	
	// Check 2 : Are there any contiguous free blocks that somehow escaped coalescing?
	iter=getLeftBlock((FREE)((char*)mem_heap_hi()+1));
	
	while(iter)
	{
		if (prev&&checkMarkedAsFree(prev)&&checkMarkedAsFree(iter))
		{
			printf("Heap Consistency Checker : %x and %x are contigous free block\n", (size_t)prev, (size_t)iter);
			flag=1;
		}
		prev=iter;
		iter=getLeftBlock(iter);
	}
	
	// Check 3 : Is every free block except 8byte actually in the free list?
	iter=getLeftBlock((FREE)((char*)mem_heap_hi()+1));
	
	while(iter)
	{
		if (checkMarkedAsFree(iter) && FSIZE(iter) != 2 * HEADER_SIZE)
		{
			if (!checkContainedInList(iter)&&!checkContainedInTree(iter))
			{
				printf("Heap Consistency Checker : %x : %08x is not contained in any list or tree\n", (size_t)iter, (size_t)FSIZE(iter));
				flag = 1;
			}
		}
		iter=getLeftBlock(iter);
	}
	
	return flag;
}
/*
 * mm_checkheap
 */
int mm_checkheap(int verbose) {
    char *bp = first_block;
    size_t* low =  mem_heap_lo();   
    size_t* high =  mem_heap_hi();        

    if (!GET_ALLOC(HDRP(first_block)) || (GET_SIZE(HDRP(first_block)) != WSIZE)) {
        if (verbose)
            printf("Error[%p]: Incorrect prologue header\n", bp);    
        return -1;
    }
    
    if (GET_ALLOC(HDRP(bp)) && (GET_SIZE(HDRP(bp)) != GET_SIZE(FTRP(bp)))) {
        if (verbose)
            printf("Error[%p]: Header and footer does not match\n", bp);
        return -1;
    }

    assert(low == mem_heap_lo());
    assert(high == mem_heap_hi());

    for (bp = NEXT_BLKP(first_block);
        GET_SIZE(HDRP(bp)) > 0;
        bp = NEXT_BLKP(bp)) {
        if ((size_t)bp > (size_t)high || (size_t)bp < (size_t)low) {
            if (verbose)
                printf("Error[%p]: Out of heap boundaries\n", bp);
            return -1;
        }
        if ((size_t)bp % 8) {
            if (verbose)
                printf("Error[%p]: Not doubleword aligned\n", bp);
            return -1;
        }
        if (!GET_ALLOC(HDRP(bp)) && 
            (GET_SIZE(HDRP(bp)) != GET_SIZE(FTRP(bp)))) {
            if (verbose)
                printf("Error[%p]: Header and footer does not match\n", bp);
            return -1;
        }        
        if (GET_ALLOC(HDRP(bp)) == 0 && GET_ALLOC(HDRP(NEXT_BLKP(bp))) == 0) {
            if (verbose){
                printf("Error: Free Blocks are not coalesced correctly [%p] and [%p] \n", bp, NEXT_BLKP(bp));
            }
            return -1;
        }
    }
    if (!(GET_ALLOC(HDRP(bp))) || (GET_SIZE(HDRP(bp)) != 0)) {
        if (verbose)
            printf("Error[%p]: Incorrect epilogue header\n", bp);    
        return -1;
    }

    return 0;
}
Пример #3
0
/*
 * add_range - As directed by request opnum in trace tracenum,
 *     we've just called the student's mm_malloc to allocate a block of 
 *     size bytes at addr lo. After checking the block for correctness,
 *     we create a range struct for this block and add it to the range list. 
 */
static int add_range(range_t **ranges, char *lo, int size, 
		int tracenum, int opnum)
{
	char *hi = lo + size - 1;
	range_t *p;
	char msg[MAXLINE];

	assert(size > 0);

	/* Payload addresses must be ALIGNMENT-byte aligned */
	if (!IS_ALIGNED(lo)) {
		sprintf(msg, "Payload address (%p) not aligned to %d bytes", 
				lo, ALIGNMENT);
		malloc_error(tracenum, opnum, msg);
		return 0;
	}

	/* The payload must lie within the extent of the heap */
	if ((lo < (char *)mem_heap_lo()) || (lo > (char *)mem_heap_hi()) || 
			(hi < (char *)mem_heap_lo()) || (hi > (char *)mem_heap_hi())) {
		sprintf(msg, "Payload (%p:%p) lies outside heap (%p:%p)",
				lo, hi, mem_heap_lo(), mem_heap_hi());
		malloc_error(tracenum, opnum, msg);
		return 0;
	}

	/* The payload must not overlap any other payloads */
	for (p = *ranges;  p != NULL;  p = p->next) {
		if ((lo >= p->lo && lo <= p-> hi) ||
				(hi >= p->lo && hi <= p->hi)) {
			sprintf(msg, "Payload (%p:%p) overlaps another payload (%p:%p)\n",
					lo, hi, p->lo, p->hi);
			malloc_error(tracenum, opnum, msg);
			return 0;
		}
	}

	/* 
	 * Everything looks OK, so remember the extent of this block 
	 * by creating a range struct and adding it the range list.
	 */
	if ((p = (range_t *)malloc(sizeof(range_t))) == NULL)
		unix_error("malloc error in add_range");

	p->next = *ranges;
	p->lo = lo;
	p->hi = hi;
	*ranges = p;
	return 1;
}
Пример #4
0
/*
 * create_space_at_endHeap - create new MALLOC chunk at end.
 * if last chunk is free, then delete that and use to malloc chunk. 
 *
 */
void *create_space_at_endHeap(size_t size)
{
	FREE last;
	int lastSize = *((size_t*)((char*)mem_heap_hi()+1-HEADER_SIZE));

	if(lastSize&1)
	{
		last = (FREE)((char*)mem_heap_hi()+1-(lastSize&-2));
		delete_free(last);
		mem_sbrk(size - FSIZE(last));
		return last;
	}

	return mem_sbrk(size);
}
Пример #5
0
/*
 * mm_check - Does not currently check anything
 */
static int mm_check(void) {
	int i;
	//Check free blocks.
	for (i = 0; i < NUM; i++) {
		int *bp = (int*) heap_st + i;
		while (1) {
			if (*bp == 0)
				break;
			//Check if the address pointed is valid.
			if ((int) (*bp) < (int) heap_st) {
				printf("The number 0x%x is not a valid heap address.\n",
						(int) *bp);
				return -1;
			}
			//Check 8 bytes alignment.
			if ((int) (*bp) % 8 != 0) {
				printf("The block 0x%x is not 8 bytes aligned.\n", (int) *bp);
				return -1;
			}
			bp = (int*) GET(HDRP(bp));
		}
	}
	//Get the data content.
	int *bp = (int *) heap_st + NUM;
	while (1) {
		bp = (int*) bp + DSIZE;
		if (bp >= (int*) mem_heap_hi())
			break;
		if (GET(HDRP(bp)) == 0)
			bp = (int*) bp + DSIZE;
		if (bp >= (int*) mem_heap_hi())
			break;
		//Check 8 bytes alignment.
		if (((int) bp) % 8 != 0) {
			printf("The block 0x%x is not 8 byte aligned.\n", (int) bp);
			return -1;
		}
		//Check if the block size is valid.
		size_t size = GET_SIZE(HDRP(bp));
		bp = (int*) bp + size;
		if ((int) *bp != 0) {
			printf("The size of block 0x%x is invalid.\n", (int) ((int*) bp
					- size));
			return -1;
		}
	}
	return 0;
}
Пример #6
0
/* Coalesce - Merge free blocks together */
int coalesce(listBlock *ptr) {
  listBlock *upperBlock = (listBlock *)(((char *)ptr) + ptr->header);
  if (upperBlock < (listBlock *)mem_heap_hi()) { // don't try to coalesce out of bounds
    if ((upperBlock->header & 0x1) == 0) { // if upperBlock is Free
      ptr->header = ptr->header + upperBlock->header; // absorb it into ptr
      int *footer = (int *)(((char *)ptr) + ptr->header - WORD_SIZE);
      *footer = ptr->header;
      upperBlock->next->prev = upperBlock->prev; // splite out the upperBlock from the free list
      upperBlock->prev->next = upperBlock->next;
    }
  }

  int *lowerFooter = (int *)(((char *)ptr) - WORD_SIZE);
  listBlock *lowerBlock = (listBlock *)(((char *)ptr) - (*lowerFooter & ~0x1));
  if ((lowerBlock->header & 0x1) == 0) { // if previous block is free
    if (lowerBlock != (listBlock *)mem_heap_lo()) { // don't coalesce with the dummy block because we don't want it to ever get allocated
      lowerBlock->header = lowerBlock->header + ptr->header;
      int *footer = (int *)(((char *)lowerBlock) + lowerBlock->header - WORD_SIZE);
      *footer = lowerBlock->header;
      return 0;
    }
  }

  return 1;
}
Пример #7
0
/*extend_heap function is used when the heap is firstly initialized, or there isn't enough
space when invoking the malloc or realloc. The extend_heap when judge whether there is space
left in the tail of the former block, it is a method to enhance the space utility.*/
void *extend_heap(size_t size_)
{
    void *bp;
    void *end = mem_heap_hi() - 3;

    int size = size_;
    if( !PRE_ALLOC_INFO(end) ){
        if(PRE_8_INFO(end)) size -= BLOCK_8;
        else size -= SIZE(end - 4);
    }
    if(size <= 0) return NULL;
    
    size = MAX(CHUNKSIZE, size);

    if((long)(bp = mem_sbrk(size)) == -1)
        return NULL;
    /* Initialize free block HDRPer/FTRPer and the epilogue HDRPer */
    size_t sign = 0 | GET_PRE_ALLOC_INFO(bp) | GET_PRE_8_INFO(bp);
    PUT_HDRP(bp, PACK(size,sign) ); /* free block HDRPer */
    PUT_FTRP(bp, PACK(size,sign) ); /* free block FTRPer */

    PUT_HDRP(GET_NEXT(bp), PACK(0,1) ); /* new epilogue HDRPer */
    
    insert_node(coalesce(bp));
    return (void *)bp;
}
/* Print the heap by iterating through it as an implicit free list. */
static void examine_heap() {
  BlockInfo *block;

  fprintf(stderr, "FREE_LIST_HEAD: %p\n", (void *)FREE_LIST_HEAD);

  for(block = (BlockInfo*)POINTER_ADD(mem_heap_lo(), WORD_SIZE); /* first block on heap */
      SIZE(block->sizeAndTags) != 0 && block < mem_heap_hi();
      block = (BlockInfo*)POINTER_ADD(block, SIZE(block->sizeAndTags))) {

    /* print out common block attributes */
    fprintf(stderr, "%p: %ld %ld %ld\t",
            (void*)block,
            SIZE(block->sizeAndTags),
            block->sizeAndTags & TAG_PRECEDING_USED,
            block->sizeAndTags & TAG_USED);

    /* and allocated/free specific data */
    if (block->sizeAndTags & TAG_USED) {
      fprintf(stderr, "ALLOCATED\n");
    } else {
      fprintf(stderr, "FREE\tnext: %p, prev: %p\n",
              (void*)block->next,
              (void*)block->prev);
    }
  }
  fprintf(stderr, "END OF HEAP\n\n");
}
Пример #9
0
/*
 * mm_check - heap consistency checker. return 0 if something is wrong, 1 otherwise.
 */
int mm_check(void)
{
    void *cur, *end;

    if(!rb_check_preorder()){
        return 0;
    }

    cur = mem_heap_lo() + MIN_BLOCK_SIZE;
    end = mem_heap_hi() - 3;
    while(cur < end){
        if(CUR_FREE(cur)){ // cur is free block
            if(PREV_FREE(cur)){ // contiguous free block
                printf("%p, %p are consecutive, but both are free.\n",
                        PREV_BLOCK(cur, CUR_SIZE_MASKED(cur)), cur);
                return 0;
            }
            if(IS_IN_RB(cur) && !rb_find_exact(cur)){ // cur is not in Red-black tree
                printf("%p is free block, but is not in Red-black tree.\n", cur);
                return 0;
            }
        }else{ // cur is allocated block
        }
        cur = NEXT_BLOCK(cur, CUR_SIZE_MASKED(cur));
    }
    return 1;
}
Пример #10
0
/*
 * mm_realloc - Implemented simply in terms of mm_malloc and mm_free,
 *              but with one added optimization.
 *
 * The optimization is that if the block is already at the end of the heap,
 * sbrk only the extra required size and update the header and footer.
 * No memcpy call is required and return the pointer that was passed in.
 */
void *mm_realloc(void *ptr, size_t size)
{
    unsigned blkSize = GET_SIZE(HDRP(ptr));
    if (realloc_size(size, 0) < blkSize) {
      return ptr;
    }

    // coalesce with sbrk
    if (NEXT_BLKP(ptr) == ADD_PTR(mem_heap_hi(), 1)) {
      unsigned allocSize = realloc_size(size, OVERHEAD) - blkSize;
      mem_sbrk(allocSize);
      alloc_ptr(ptr, realloc_size(size, OVERHEAD));

      // set allocation before the last block
      PUT_INT(HDRP(NEXT_BLKP(ptr)), 1);

      return ptr;
    }
/*
    // allocate coalesce with next free block

    // allocate coalesce with prev free block
*/
    void *newptr = mm_malloc((unsigned)size);
    if (newptr == NULL)
      return NULL;

    unsigned cpysize = MIN(blkSize - OVERHEAD, (unsigned)size);
    memcpy_8(newptr, ptr, cpysize);
    mm_free(ptr);

    return newptr;
}
Пример #11
0
Файл: mm.c Проект: YurieCo/hsi
/* Initialize the allocator. */
int mm_init () {
  // Head of the free list.
  BlockInfo *firstFreeBlock;
  // Initial heap size: WORD_SIZE byte header (stores pointer to head
  // of free list), MIN_BLOCK_SIZE bytes of space, WORD_SIZE byte footer.
  int initsize = WORD_SIZE+MIN_BLOCK_SIZE+WORD_SIZE;

  int totalSize;

  void* mem_sbrk_result = mem_sbrk(initsize);
  //  printf("mem_sbrk returned %p\n", mem_sbrk_result);
  if ((int)mem_sbrk_result == -1) {
		printf("ERROR: mem_sbrk failed in mm_init, returning %p\n", 
		         mem_sbrk_result);
		exit(1);
  }

  firstFreeBlock = (BlockInfo*)POINTER_ADD(mem_heap_lo(), WORD_SIZE);

  // total usable size is full size minus header and footer words.
  totalSize = initsize - WORD_SIZE - WORD_SIZE;
  // initialize the free block
  firstFreeBlock->sizeAndTags = totalSize | TAG_PRECEDING_USED;
  firstFreeBlock->next = NULL;
  firstFreeBlock->prev = NULL;
  // boundary tag
  *((int*)POINTER_ADD(firstFreeBlock, totalSize - WORD_SIZE)) = totalSize | TAG_PRECEDING_USED;
  
  // Tag "useless" word at end of heap as used.
  *((int*)POINTER_SUB(mem_heap_hi(), 3)) = TAG_USED;

  // set the head of the free list to this new free block.
  FREE_LIST_HEAD = firstFreeBlock;
  return 0;
}
Пример #12
0
static void checkblock(void *bp)
{
	size_t halloc = GET_ALLOC(HDRP(bp));

	// check if free block is inside heap
	if ((bp < mem_heap_lo()) || (mem_heap_hi() < bp)) {
		printf("mm_check: block pointer %p outside of heap\n",bp);
		fflush(stdout);
		exit(0);
	}
		
	// alignment check
	if ((size_t)bp % 8) {
		printf("Error: %p is not doubleword aligned\n", bp);
		exit(0);
	}
	
	// allocated block does not have footer	
	if (!halloc) {
		if (GET(HDRP(bp)) != GET(FTRP(bp))) {
			printf("Error: header does not match footer\n");
			exit(0);
		}
	}
}
Пример #13
0
/**
 * extend_heap - Extend the heap by number of bytes adjusted_size.
 *
 * This differs from the example extend_heap function in that the parameter
 * passed is in BYTES rather than WORDS. Constantly converting between the two
 * is confusing and unnecessary.
 *
 * Furthermore, it should be a size already adjusted to fit byte and header
 * alignment. This function merely sets header/footer/successor as needed.
 */
static void *extend_heap(size_t adjusted_size)
{
	char *bp;
	size_t prev_alloc;

	TRACE("Entering extend_heap(adjusted_size=%u)\n", adjusted_size);

	if ((long)(bp = mem_sbrk(adjusted_size)) == -1)
		return NULL;

	/* Initialize free block header/footer and the epilogue header.
		heap_end points to one byte before the next payload, so reading
		the PREVALLOC field of heap_end + 1 will yield the actual prev-alloc
		for the block just before the end of the heap. */
	prev_alloc = GET_PREVALLOC(heap_end + 1);

	/* Free block header */
	PUTW(GET_BLOCKHDR(bp), PACK(adjusted_size, prev_alloc));

	/* Free block header */
	PUTW(GET_BLOCKFTR(bp), PACK(adjusted_size, prev_alloc));

	/* New epilogue header */
	PUTW(GET_BLOCKHDR(GET_NEXTBLOCK(bp)), PACK(0xEA7F00D0, THISALLOC));
	heap_end = mem_heap_hi();

	TRACE("<<<---Leaving extend_heap() with a call to coalesce()\n");
	/* Coalesce if the previous block was free */
	return coalesce(bp); /* coalesce handles adding block to free list */
}
Пример #14
0
/*
 * mm_realloc - Change the size of a block.
 */
void *mm_realloc(void *ptr, size_t size)
{
#ifdef MM_CHECK
    if (!ptr) return mm_malloc(size);
    if (!size) return mm_free(ptr);
#endif

    void *now = mm_restore_header(ptr);
    void *dest;
    size_t now_size = MM(now)->size;
    size_t need_size = MM_HEADER_SIZE + ALIGN(size);

    // try to merge useable blocks
    while (now_size < need_size && mm_merge(now, &now_size));

    if (now_size >= need_size) {
        // the block can be locally extensed and splitting is possible
        return mm_split(now, now_size, need_size);
    } else {
        if ((now + now_size - 1) == mem_heap_hi()) {
            // the block is the last block and it can be extensed
            return mm_break(now, now_size, need_size);
        } else {
            // need to allocate a new block and copy data to it
            dest = mm_malloc(size);
            memcpy(dest, ptr, MM(now)->size - MM_HEADER_SIZE);
            mm_free(ptr);
            return dest;
        }
    }
}
Пример #15
0
/*
 * getRightBlock - returns a block on the right side of target
 * returns NULL if doens't exists.
 *
 */
void* getRightBlock(void* target)
{
	void* rightBlock = (FREE)((void*)target+FSIZE(target));
	if (rightBlock<mem_heap_hi()+1)
	{
		return rightBlock;
	}
	return NULL;
}
Пример #16
0
void print_heap()
{
    hblock *bp = mem_heap_lo();
    while(bp < (hblock *) mem_heap_hi()) {
        printf("%s block at %p, size %d\n", 
               GET_ALLOC(bp) ? "allocated":"free", bp, GET_SIZE(bp));
        bp = (hblock *) NEXT_BLKP(bp); 
    }
}
Пример #17
0
void print_the_heap()          			// printing the information related to blocks in the heap 
{                 
	blockHdr *bp = mem_heap_lo();
	while(bp<(blockHdr *)mem_heap_hi()){
		printf("%s block at:  %p,size: %d\n",(bp->size&1)?"allocated":"free",bp ,(int)(bp->size & ~1));
		bp = (blockHdr *)((char *)bp +(bp->size & ~1));

	}
}
Пример #18
0
/*
* checkBlock - Checks a block for consistency
* Checks prev and next pointers to see if they are within heap boundaries.
* Checks for 8-byte alignment.
* Checks header and footer for consistency.
*
* This function takes a block pointer (to a block for examinination) as a
* parameter.
*/
static void checkBlock(void *bp)
{
// Reports if the next and prev pointers are within heap bounds
if (NEXT_FREEP(bp)< mem_heap_lo() || NEXT_FREEP(bp) > mem_heap_hi())
printf("Error: next pointer %p is not within heap bounds \n"
, NEXT_FREEP(bp));
if (PREV_FREEP(bp)< mem_heap_lo() || PREV_FREEP(bp) > mem_heap_hi())
printf("Error: prev pointer %p is not within heap bounds \n"
, PREV_FREEP(bp));
/* Reports if there isn't 8-byte alignment by checking if the block pointer
* is divisible by 8.
*/
if ((size_t)bp % 8)
printf("Error: %p is not doubleword aligned\n", bp);
// Reports if the header information does not match the footer information
if (GET(HDRP(bp)) != GET(FTRP(bp)))
printf("Error: header does not match footer\n");
}
Пример #19
0
Файл: mm.c Проект: morlowsk/Work
void *coalesce(size_t *bp) {
    size_t *next = (size_t *)((char *)bp + (*bp & ~1L));
    size_t *prev = (size_t *)((char *)bp - ((*(size_t *)((char *)bp - SIZE_T_SIZE)) & ~1L));

    int prev_alloc, next_alloc;
    blockHdr *head = (blockHdr *)mem_heap_lo();
    blockHdr *v = (blockHdr *)bp;              
 
    if (prev > (size_t *)mem_heap_lo()) {
        prev_alloc = *prev & 1;
    }
    else {
        prev_alloc = 1;
    }
    if (next < ((size_t *)mem_heap_hi())) {
        next_alloc = *next & 1;
    }
    else {
        next_alloc = 1;
    }
    if (prev_alloc && next_alloc) {
        v->next_p = head->next_p;
        v->prior_p = head;
        head->next_p = v;
        v->next_p->prior_p = v;
        return v;
    }
    else if (!prev_alloc && next_alloc) {//if previous free
        *prev += (*bp & ~1); //bp is not yet freed 
        *(size_t *) ((char *)bp + (*bp & ~1) - SIZE_T_SIZE) = *prev;
        return prev;
    }
    else if (prev_alloc && !next_alloc) { //if next free
        *bp += (*next & ~1);
        *(size_t *) ((char *)next + (*next & ~1) - SIZE_T_SIZE) = *bp;
        
        v->next_p = ((blockHdr *) next)->next_p;
        v->prior_p = ((blockHdr *) next)->prior_p;
        v->prior_p->next_p = v;
        v->next_p->prior_p = v;
        return v;
       
    }
    else if (!prev_alloc && !next_alloc) {
        *prev += (*next & ~1) + (*bp & ~1);
        *(size_t *) ((char *)next + (*next & ~1)  - SIZE_T_SIZE) = *prev;
        /*((blockHdr *) prev)->next_p = ((blockHdr *) next)->next_p;
        ((blockHdr *) prev)->next_p->prior_p = (blockHdr *) prev;*/

        ((blockHdr*)next)->prior_p->next_p = ((blockHdr *)next)->next_p;
        ((blockHdr*)next)->next_p->prior_p = ((blockHdr *)next)->prior_p;

        return prev;
    }
        return NULL;
} 
Пример #20
0
/**********************************************************
 * is_in_heap
 * Checks if the block pointer is in heap. Prints an error
 * message if the block is outside the heap
 **********************************************************/
int is_in_heap(void *bp)
{
    if (bp < mem_heap_lo() || bp > mem_heap_hi())
    {
        PRINTDBG (("The block is not on the heap\n"));
        return 0;
    }
    
    return 1;
}
Пример #21
0
void print_heap() {
  blockHdr *bp = mem_heap_lo();
  while (bp < (blockHdr *)mem_heap_hi()) {
    printf("%s block at %p, size %d\n",
           (bp->size&1)?"allocated":"free",
           bp,
           (int)(bp->size & ~1));
    bp = (blockHdr *)((char *)bp + (bp->size & ~1));
  }
}
Пример #22
0
Файл: mm.c Проект: morlowsk/Work
void print_heap(){
    blockHdr *bp = mem_heap_lo();
    int i = 0;
    while (bp < (blockHdr *) mem_heap_hi()) {
        printf("%d. %s block at %p, size %ld + \n", i,
                (bp->size&1)?"allocated":"free",
                bp, (long) (bp->size & ~1));
        bp = (blockHdr *) ((char *) bp + (bp->size & ~1));
        i++;
    }
}
Пример #23
0
/*
 * mm_malloc - Allocate a block
 *
 * If there exists a free block where the request fits, get the smallest one, segment it and allocate.
 * If there is no such block, increase brk.
 */
void* mm_malloc(size_t size)
{
    size_t block_size, next_block_size;
    void *free_block, *next_block;
    
    block_size = ALIGN(HEADER_SIZE + size);
    block_size = block_size < MIN_BLOCK_SIZE ? MIN_BLOCK_SIZE : block_size;

    free_block = rb_find(block_size);
    if(free_block == rb_null){ // proper free block not found
        /* set free_block to the end of last block in heap */
        free_block = mem_heap_hi() - 3;
        if(PREV_FREE(free_block)){ // if the last block is free
            /* set free_block to the last block */
            free_block -= PREV_SIZE_MASKED(free_block);
            if(IS_IN_RB(free_block)){
                rb_delete(free_block);
            }
            /* this block is smaller than request, so increase brk */
            mem_sbrk(block_size - CUR_SIZE_MASKED(free_block));
        }else{ // if the last block is not free
            mem_sbrk(block_size);
        }
    }else{
        /* will be allocated, so delete from tree first */
        rb_delete(free_block);
        /* if the block is bigger than request, segment it */
        if((next_block_size = CUR_SIZE_MASKED(free_block) - block_size) > 0){
            next_block = NEXT_BLOCK(free_block, block_size);
            CUR_SIZE(next_block) = PREV_SIZE(NEXT_BLOCK(next_block, next_block_size)) = next_block_size | 1;
            if(IS_IN_RB(next_block)){
                rb_insert(next_block);
            }
        }
    }
    CUR_SIZE(free_block) = PREV_SIZE(NEXT_BLOCK(free_block, block_size)) = block_size;

#ifdef DEBUG
    printf("mm_malloc(%u) called\n", size);
    printf("free_block = %p\n", free_block);
    rb_print_preorder();
    printf("\n");
#endif /* DEBUG */

#ifdef CHECK
    if(!mm_check()){
        rb_print_preorder();
        exit(0);
    }
#endif /* CHECK */

    return USER_BLOCK(free_block);
}
Пример #24
0
/*
 * checkFreeNodes - function that checks correctness of the blocks in
 * the free list
 */
static void checkFreeNodes(void *bp)
{
  /* Seperate condition for free_listp since it does not have a
   * previous pointer.
   */

  if(bp == free_listp)
    {
      /* Checking that free_listp indeed points to a free block. */
      if(GET_ALLOC(HDRP(bp)))
	printf("Error: Freelistp points to an allocated block.\n");

      /* Free_listp must point to a valid block and must not be
       * out of bounds */
      if(!(bp > mem_heap_lo() && bp < mem_heap_hi()))
	printf("Error: Free list pointer out of heap bounds.\n");

      /* Previous pointer of free_listp
       * must point nowhere (nil). */
      if(PREV_FREE(bp) != 0 )
	printf("Error: Free pointer is not null.\n");
      return;
    }

  /* Checking that bp is indeed pointing to a free block */
  if(GET_ALLOC(HDRP(bp)) != 0)
    printf("Error: There exists an allocated block in the free list.\n");

  /* Check that next and prev pointers in consecutive blocks are consistent
   * Next pointer of previous block points to current block and previous pointer
   * of next block points to current block */
  // Split one print statement into 2 to not cross the 80 character limit.
  if(PREV_FREE(bp) && NEXT_FREE(PREV_FREE(bp)) != bp)
    {
      printf("Error: Next pointer of previous free block ");
      printf("not pointing to current block.\n");
    }

  if(NEXT_FREE(bp) && PREV_FREE(NEXT_FREE(bp)) != bp)
    {
      printf("Error: Previous pointer of next free block ");
      printf("not pointing to current block.\n");
    }

  /* Check that coalescing was correct at the free block pointed to by
     bp. The previous and next blocks must both be allocated.*/
  if(!GET_ALLOC(HDRP(NEXT_BLKP(bp))) || !GET_ALLOC(HDRP(PREV_BLKP(bp))))
    printf("Error: Contiguous free blocks in the heap\n");


}
Пример #25
0
void checklist(void) 
{
	void* bp = heap_listp;
	void* prev_ptr;
	//int  prev_alloc = 1;
	int i;

	dbg1("[IN ] : checklist\n");
	
  /* go through each segregated free list */
	for ( i = 0; i <= MAXCLASS; i++ ) {
		if (verbose)
			printlist(i);
		
		bp = GET_FREE_LISTP(i);
		prev_ptr = NULL;
		while( bp != NULL) {
			/* see if pointer is within heap */
			if ((bp < mem_heap_lo()) || (mem_heap_hi() < bp)) {
				printf("mm_check: free block pointer %p outside of heap\n",bp);
				fflush(stdout);
				exit(0);
			}
			/* make sure block is truly free */
			if (GET_ALLOC(HDRP(bp))) {
				printf("mm_check: free block list %d has allocated block\n", i);
				fflush(stdout);
				exit(0);
			}
			/* make sure block is not smaller than min block */
			if (GET_SIZE(HDRP(bp)) < OVERHEAD + 2*DSIZE) {
				printf("mm_check: block too small in list %d with block at %p\n", i, bp);
				printf("mm_check: %x\n", GET_SIZE(HDRP(bp)));
				fflush(stdout);
				exit(0);
			}
			/* make sure previous pointer is correct */
			if (PREV_FREE_BLKP(bp) != prev_ptr) {
				printf("mm_check: previous block ptr in list %d does not point to previous block\n", i);
				fflush(stdout);
				exit(0);
			}
			/* go to next free block */
			prev_ptr = bp;
			bp = (void*)NEXT_FREE_BLKP(bp);
		}
	}

	dbg1("[OUT] : checklist\n");
	return;
}
Пример #26
0
/*
 * checkblock - checks basic invariants of a block in the heap list
 */
static void checkblock(void *bp)
{
  /* Checking for double word alignment */
  if ((size_t)bp % 8)
    printf("Error: %p is not doubleword aligned\n", bp);

  /* Header must match footer for allocation bit and size */
  if (GET(HDRP(bp)) != GET(FTRP(bp)))
    printf("Error: header does not match footer\n");

  /* Block pointer must be within the heap boundaries */
  if(bp > mem_heap_hi() || bp < mem_heap_lo())
    printf("Error: block pointer not within heap boundaries.\n");
}
Пример #27
0
/*
 * mm_merge - Try to merge with next free block.
 */
inline int mm_merge(void *ptr, size_t *p_size)
{
    void *next = ptr + *p_size;
    size_t next_size = MM(next)->size;

    // if the next block can be merged
    if ((next - 1) != mem_heap_hi() && SIGN_CHECK(next_size)) {
        *p_size += SIGN_MARK(next_size);
        mm_put_header(ptr, SIGN_MARK(*p_size));
        return -1;
    } else {
        return 0;
    }
}
Пример #28
0
/*
 * mm_exit - finalize the malloc package.
 */
void mm_exit(void)
{
    void *cur, *end;

    cur = mem_heap_lo() + MIN_BLOCK_SIZE;
    end = mem_heap_hi() - 3;
    while(cur < end){
        /* check if there are allocated blocks remaining */
        if(!CUR_FREE(cur)){
            printf("memory leak at %p is detected.\n", cur);
            mm_free(cur + HEADER_SIZE);
        }
        cur = NEXT_BLOCK(cur, CUR_SIZE_MASKED(cur));
    }
}
Пример #29
0
/*
 * mm_print - Print block list for debug purpose.
 */
void mm_print(void)
{
    void *now = mem_heap_lo();
    size_t now_size = 0;

    printf("\n");

    // scan the block list
    while ((now - 1) != mem_heap_hi()) {
        now_size = MM(now)->size;
        printf("pos: %x - head: %x\n", (unsigned) now, now_size);

        // visit the next block
        now += SIGN_CHECK(now_size) ? SIGN_MARK(now_size) : now_size;
    }
}
Пример #30
0
static void print_blk(char *cur_blk)
{
    cur_blk = cur_blk;
    dbg_printf("\n    address:   %d\n", (unsigned long)cur_blk);
    dbg_printf("    hdr-size:  %d\n", GET_SIZE(HDRP(cur_blk)));
    dbg_printf("    hdr-alloc: %d\n", GET_ALLOC(HDRP(cur_blk)));
    dbg_printf("    ftr-size:  %d\n", GET_SIZE(FTRP(cur_blk)));
    dbg_printf("    ftr-alloc: %d\n", GET_ALLOC(FTRP(cur_blk)));
    if (GET_ALLOC(HDRP(cur_blk)) == 0)
    {
        dbg_printf("    pred:      %d\n", (unsigned long)REAL_ADDR(GET(PRED(cur_blk))));
        dbg_printf("    succ:      %d\n", (unsigned long)REAL_ADDR(GET(SUCC(cur_blk))));
    }
    dbg_printf("    heap_end:  %d\n", (unsigned long)(mem_heap_hi() + 1));
    dbg_printf("****************************\n");
}