Example #1
0
/* Get more heap space of size at least reqSize. */
static void requestMoreSpace(size_t reqSize) {
  size_t pagesize = mem_pagesize();
  size_t numPages = (reqSize + pagesize - 1) / pagesize;
  BlockInfo *newBlock;
  size_t totalSize = numPages * pagesize;
  size_t prevLastWordMask;
  void* mem_sbrk_result = mem_sbrk(totalSize);
  if ((size_t)mem_sbrk_result == -1) {
    printf("ERROR: mem_sbrk failed in requestMoreSpace\n");
    exit(0);
  }
  newBlock = (BlockInfo*)UNSCALED_POINTER_SUB(mem_sbrk_result, WORD_SIZE);
  /* initialize header, inherit TAG_PRECEDING_USED status from the
     previously useless last word however, reset the fake TAG_USED
     bit */
  printf("newBlock: %p\n", (void *) newBlock);

  prevLastWordMask = newBlock->sizeAndTags & TAG_PRECEDING_USED;
  newBlock->sizeAndTags = totalSize | prevLastWordMask;
  // Initialize boundary tag.
  ((BlockInfo*)UNSCALED_POINTER_ADD(newBlock, totalSize - WORD_SIZE))->sizeAndTags =
    totalSize | prevLastWordMask;
  /* initialize "new" useless last word
     the previous block is free at this moment
     but this word is useless, so its use bit is set
     This trick lets us do the "normal" check even at the end of
     the heap and avoid a special check to see if the following
     block is the end of the heap... */
  *((size_t*)UNSCALED_POINTER_ADD(newBlock, totalSize)) = TAG_USED;

  // Add the new block to the free list and immediately coalesce newly
  // allocated memory space
  insertFreeBlock(newBlock);
  coalesceFreeBlock(newBlock);
}
Example #2
0
/**
 * mm_init - Initialize the malloc package.
 */
int mm_init(void)
{
	TRACE(">>>Entering mm_init()\n");
	mem_init();

	#ifdef DO_MM_CHECK
		/* initialize the ENTIRE heap provided by memlib to 0x00 */
		memset(mem_heap_lo(), 0, MAX_HEAP);
	#endif

	/*Each element in free_lists starts off as the empty head of a linked list*/
	memset(free_lists, (int)NULL, sizeof(free_lists));

	/* Initialize write-once variables */
	PAGE_SIZE = mem_pagesize();
	ADJUSTED_PAGESIZE = ADJUST_BYTESIZE((PAGE_SIZE*2));

	/* Initially allocate 1 page of memory plus room for
		the prologue and epilogue blocks and free block header */
	if((heap_start = mem_sbrk(ADJUSTED_PAGESIZE + (4 * WSIZE))) == NULL)
		return -1;

	heap_end = mem_heap_hi();

	/* Alignment word */
	PUTW(heap_start, 0x8BADF00D);

	/* Prologue header */
	PUTW(heap_start + (1 * WSIZE), PACK(DSIZE, THISALLOC | PREVALLOC));
	PUTW(heap_start + (2 * WSIZE), PACK(DSIZE, THISALLOC | PREVALLOC));

	/* Epilogue header */
	PUTW(heap_start + ADJUSTED_PAGESIZE + 3	* WSIZE, PACK(0xEA7F00D0, THISALLOC));

	/* Setup initial free block */
	PUTW(heap_start + (3 * WSIZE), PACK(ADJUSTED_PAGESIZE, PREVALLOC));
	PUTW((heap_end - WSIZE + 1) - WSIZE, PACK(ADJUSTED_PAGESIZE, PREVALLOC));
	add_to_list(heap_start + (4 * WSIZE), calc_list_index(ADJUSTED_PAGESIZE));

	RUN_MM_CHECK();
	TRACE("<<<---Leaving mm_init()\n");
	return 0;
}
Example #3
0
/**********************************************************
 * mm_check
 * Check the consistency of the memory heap
 * Return nonzero if the heap is consistant.
 *********************************************************/
int mm_check(void)
{
#ifdef DEBUG_BUILD

    int i;
    dlist *current;
    void *bp; //To point at the start of the heap
    size_t size = 0; //To measure the total size of blocks on the heap

    // Check if every block in free list is actually marked free.
    // If a allocated block is in the free list then it may result in segmentation faults
    // while accessing the prev and next pointers. It will also result in the allocater manipulating 
    // memory allocated to user which will be nasty!

    for(i = 0; i < NUM_SEG_LIST; i++) {
        current = sep_list_head[i];
    
        while (current != NULL) {
            // Check if block is in heap
            if (is_in_heap((void*)current) == 0)
                return 0;

            if (GET_ALLOC(HDRP((void*)current))) {
                PRINTDBG (("block (%p) in free list is allocated!\n", current));
                return 0;
            }
            current = current->next;
        }
    }

    // Check if there exist any free blocks that may have escaped coalescing. 
    // If found, these cases result in internal fragmentation.
    for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp))
    {
        // Check if the current block is free and the next block is also free
        // Since this is done in a sequential manner, we don't need to check the previous blk
        if (!GET_ALLOC(HDRP(bp)) && (!GET_ALLOC(HDRP(NEXT_BLKP(bp))))) {
            PRINTDBG (("Consecutive blocks (%p, %p) have escaped coalescing!\n", bp, NEXT_BLKP(bp)));
            return 0;
        }
    }

    for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) {
        if (bp < mem_heap_lo() || bp > mem_heap_hi()) {
            PRINTDBG (("Block is outside the heap.\n"));
            return 0;
        }
        else {
            size += GET_SIZE(HDRP(bp));     //Add the size of the current block to the total size of the calculated blocks on the heap so far
        }
    }
            
    if (size == mem_heapsize())
        PRINTDBG (("The total size of all blocks on the heap match the heap size.\n"));

    if (mem_heapsize() > mem_pagesize())   //Check if heap size exceeded systems page size  
        PRINTDBG (("Heap size is more than page size. TLB misses might occur\n"));

    char c;
    scanf("%c\n", &c);

#endif
    return 1;
}