Ejemplo n.º 1
0
/* Allocate a block of size size and return a pointer to it. */
void * mm_malloc (size_t size) {
  size_t reqSize;
  BlockInfo * ptrFreeBlock = NULL;
  //Zero-size requests get NULL;
  if (size == 0){
    return NULL;
  }
  //Add one word for the initial size header.
  //Note that we don't need to boundary tag when the block is used!
  if (size <= MIN_BLOCK_SIZE) {
   // Make sure we allocate enough space for a blockInfo in case we
   // free this block (when we free this block, we'll need to use the
   // next pointer, the prev pointer, and the boundary tag).
   reqSize = MIN_BLOCK_SIZE;
 } else {
   // Round up for correct alignment
   reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT);
 }
  printf("Begin malloc of reqSize: %zd \n", reqSize);
  printf("Free list head: %p\n", FREE_LIST_HEAD);
  examine_heap();
  while ((ptrFreeBlock = searchFreeList(reqSize)) == NULL){
    requestMoreSpace(reqSize);
    printf("Finished space request\n");
  }
  removeFreeBlock(ptrFreeBlock);
  placeBlock(ptrFreeBlock, reqSize);
  printf("Completed malloc\n");
  printf("Pointer free block: %p\n", ptrFreeBlock);
  examine_heap();
  return UNSCALED_POINTER_ADD(ptrFreeBlock, WORD_SIZE);
}
Ejemplo n.º 2
0
/* Initialize the allocator. */
int mm_init () {
  // Head of the free list.
  BlockInfo *firstFreeBlock;

  // Initial heap size: WORD_SIZE byte heap-header (stores pointer to head
  // of free list), MIN_BLOCK_SIZE bytes of space, WORD_SIZE byte heap-footer.
  size_t initSize = WORD_SIZE+MIN_BLOCK_SIZE+WORD_SIZE;
  size_t totalSize;

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

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

  // Total usable size is full size minus heap-header and heap-footer words
  // NOTE: These are different than the "header" and "footer" of a block!
  // The heap-header is a pointer to the first free block in the free list.
  // The heap-footer is used to keep the data structures consistent (see
  // requestMoreSpace() for more info, but you should be able to ignore it).
  totalSize = initSize - WORD_SIZE - WORD_SIZE;

  // The heap starts with one free block, which we initialize now.
  firstFreeBlock->sizeAndTags = totalSize | TAG_PRECEDING_USED;
  firstFreeBlock->next = NULL;
  firstFreeBlock->prev = NULL;
  // boundary tag
  *((size_t*)UNSCALED_POINTER_ADD(firstFreeBlock, totalSize - WORD_SIZE)) = totalSize | TAG_PRECEDING_USED;

  // Tag "useless" word at end of heap as used.
  // This is the is the heap-footer.
  *((size_t*)UNSCALED_POINTER_SUB(mem_heap_hi(), WORD_SIZE - 1)) = TAG_USED;

  // set the head of the free list to this new free block.
  FREE_LIST_HEAD = firstFreeBlock;
  printf("Heap after initialization\n");
  examine_heap();
  return 0;
}
Ejemplo n.º 3
0
void split_block(BlockInfo * ptrFreeBlock, size_t totalSize, size_t precedingBlockUseTag){
  printf("Splitting\n");
  BlockInfo * splitBlock = NULL;
  BlockInfo * splitBlockFooter = NULL;
  BlockInfo * nextBlock = NULL;
  size_t splitBlockSize;
  size_t ptrFreeBlockSize;
  ptrFreeBlockSize = SIZE(ptrFreeBlock->sizeAndTags);
  splitBlock = (BlockInfo *) UNSCALED_POINTER_ADD(ptrFreeBlock, ptrFreeBlockSize);
  splitBlockSize =  totalSize - ptrFreeBlockSize;
  splitBlock->sizeAndTags = splitBlockSize | TAG_PRECEDING_USED;
  splitBlockFooter = (BlockInfo *)  UNSCALED_POINTER_ADD((void*)splitBlock, splitBlockSize - WORD_SIZE);
  splitBlockFooter->sizeAndTags =  splitBlock->sizeAndTags;
  nextBlock = (BlockInfo *) UNSCALED_POINTER_ADD((void *) splitBlock, splitBlockSize);
  set_next_block(nextBlock,  0);
  insertFreeBlock(splitBlock);
  coalesceFreeBlock(splitBlock);
  examine_heap();
}
Ejemplo n.º 4
0
void* mm_realloc(void* ptr, size_t size) {
  printf("Beginning realloc\n");
  size_t payLoadSize;
  BlockInfo * blockInfo;
  if (ptr == NULL){
    if (size == 0){
      mm_free(ptr);
    }
    else{
      mm_malloc(size);
    }
  }
  else if (ptr != NULL){
    blockInfo = (BlockInfo *) ptr;
    payLoadSize = MIN(SIZE(blockInfo->sizeAndTags), size);
    //Cases: payLoadSize is larger than original block -- copy up to size of original block.
    //Cases: payLoadSize is smaller than original block -- split block?
    memcpy(ptr, ptr, payLoadSize);
  }
  examine_heap();
  // ... implementation here ...
  return NULL;
}
Ejemplo n.º 5
0
Archivo: mm.c Proyecto: ndukweiko/mm
/* 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) {
    examine_heap();
    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 */
  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);
}