Exemple #1
0
/* Coalesce 'oldBlock' with any preceeding or following free blocks. */
static void coalesceFreeBlock(BlockInfo* oldBlock) {
  BlockInfo *blockCursor;
  BlockInfo *newBlock;
  BlockInfo *freeBlock;
  // size of old block
  size_t oldSize = SIZE(oldBlock->sizeAndTags);
  // running sum to be size of final coalesced block
  size_t newSize = oldSize;

  // Coalesce with any preceding free block
  blockCursor = oldBlock;
  while ((blockCursor->sizeAndTags & TAG_PRECEDING_USED)==0) {
    // While the block preceding this one in memory (not the
    // prev. block in the free list) is free:

    // Get the size of the previous block from its boundary tag.
    size_t size = SIZE(*((size_t*)UNSCALED_POINTER_SUB(blockCursor, WORD_SIZE)));
    // Use this size to find the block info for that block.
    freeBlock = (BlockInfo*)UNSCALED_POINTER_SUB(blockCursor, size);
    // Remove that block from free list.
    removeFreeBlock(freeBlock);
    // Count that block's size and update the current block pointer.
    newSize += size;
    blockCursor = freeBlock;
  }
  newBlock = blockCursor;

  // Coalesce with any following free block.
  // Start with the block following this one in memory
  blockCursor = (BlockInfo*)UNSCALED_POINTER_ADD(oldBlock, oldSize);
  while ((blockCursor->sizeAndTags & TAG_USED)==0) {
    // While the block is free:

    size_t size = SIZE(blockCursor->sizeAndTags);
    // Remove it from the free list.
    removeFreeBlock(blockCursor);
    // Count its size and step to the following block.
    newSize += size;
    blockCursor = (BlockInfo*)UNSCALED_POINTER_ADD(blockCursor, size);
  }

  // If the block actually grew, remove the old entry from the free
  // list and add the new entry.
  if (newSize != oldSize) {
    // Remove the original block from the free list
    removeFreeBlock(oldBlock);

    // Save the new size in the block info and in the boundary tag
    // and tag it to show the preceding block is used (otherwise, it
    // would have become part of this one!).
    newBlock->sizeAndTags = newSize | TAG_PRECEDING_USED;
    // The boundary tag of the preceding block is the word immediately
    // preceding block in memory where we left off advancing blockCursor.
    *(size_t*)UNSCALED_POINTER_SUB(blockCursor, WORD_SIZE) = newSize | TAG_PRECEDING_USED;

    // Put the new block in the free list.
    insertFreeBlock(newBlock);
  }
  return;
}
Exemple #2
0
        VboBlock* Vbo::freeBlock(VboBlock& block) {
#ifdef _DEBUG_VBO
            checkBlockChain();
            checkFreeBlocks();
#endif

            VboBlock* previous = block.m_previous;
            VboBlock* next = block.m_next;
            
            m_freeCapacity += block.capacity();
            block.m_free = true;
            
            if (previous != NULL && previous->free() && next != NULL && next->free()) {
                resizeBlock(*previous, previous->capacity() + block.capacity() + next->capacity());
                if (m_last == next) m_last = previous;
                removeFreeBlock(*next);
                previous->insertBetween(previous->m_previous, next->m_next);
                delete █
                delete next;
                return previous;
            }
            
            if (previous != NULL && previous->free()) {
                resizeBlock(*previous, previous->capacity() + block.capacity());
                if (m_last == &block) m_last = previous;
                previous->insertBetween(previous->m_previous, next);
                delete █
                return previous;
            }
            
            if (next != NULL && next->free()) {
                if (m_last == next) m_last = █
                removeFreeBlock(*next);
                block.m_capacity += next->capacity();
                block.m_free = true;
                block.insertBetween(previous, next->m_next);
                insertFreeBlock(block);
                delete next;
                return █
            }
            
            insertFreeBlock(block);

#ifdef _DEBUG_VBO
            checkBlockChain();
            checkFreeBlocks();
#endif

            return █
        }
Exemple #3
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);
}
Exemple #4
0
//set block allocates the chosen block by removing it from the free list/re-adding the remainder(from mem_sbrk) to the freelist
static void setBlock(BlockInfo * block, size_t reqSize, size_t precedingBlockUseTag ){
  BlockInfo * remainder;
  size_t size_allocated;
  size_allocated = (size_t)SIZE(block->sizeAndTags); //get the size of the block
  removeFreeBlock(block); //if we're allocating, we should remove from the free list
  if( (size_allocated - reqSize) > MIN_BLOCK_SIZE){ //calls to mem_sbrk allocate more memory than we need, let's put back what's left over after filling the request.
    block->sizeAndTags = reqSize | precedingBlockUseTag; //turn on the TAG_PRECEDING_USED for the else clause of mm_malloc
    remainder = (BlockInfo *)UNSCALED_POINTER_ADD(block, reqSize);//reqSize is the payload of the block we're trying to allocate, we move past that portion to access the remainder
    remainder->sizeAndTags = ((size_allocated - reqSize) | TAG_PRECEDING_USED);//the remainder is the block in the list immediately following the allocated. need to 
    //turn on the preceding block used flag
    *((size_t *)UNSCALED_POINTER_ADD(block, (reqSize - WORD_SIZE))) = reqSize;//boundary tag for allocated block
    *((size_t *)UNSCALED_POINTER_ADD(block, (size_allocated - WORD_SIZE))) = (size_allocated - reqSize); //size for the remainder is the size actually allocated - the desired size 
    insertFreeBlock(remainder);//re-insert remainder into the freeList
    
  }

  else{
    *((size_t* )UNSCALED_POINTER_ADD(block,(size_allocated - WORD_SIZE))) = size_allocated;
    remainder = (BlockInfo *)UNSCALED_POINTER_ADD(block, size_allocated);
    remainder->sizeAndTags = remainder->sizeAndTags | TAG_PRECEDING_USED;
  }

  block->sizeAndTags = block->sizeAndTags | TAG_USED;
  block->sizeAndTags = block->sizeAndTags | precedingBlockUseTag;
}
Exemple #5
0
 void Vbo::resizeBlock(VboBlock& block, size_t newCapacity) {
     if (block.capacity() == newCapacity) return;
     if (block.free()) {
         removeFreeBlock(block);
         block.m_capacity = newCapacity;
         insertFreeBlock(block);
     }
 }
Exemple #6
0
        VboBlock* Vbo::packBlock(VboBlock& block) {
            VboBlock* first = block.m_next;
            if (first == NULL)
                return NULL;
            
            VboBlock* previous = NULL;
            VboBlock* last = first;
            size_t size = 0;
            size_t address = first->address();
            
            do {
                last->m_address -= block.capacity();
                size += last->capacity();
                previous = last;
                last = last->m_next;
            } while (last != NULL && !last->free());
            
            memmove(m_buffer + block.address(), m_buffer + address, size);
            
            if (last != NULL) {
                last->m_address -= block.capacity();
                resizeBlock(*last, last->capacity() + block.capacity());
            } else {
                VboBlock* newBlock = new VboBlock(*this, previous->address() + previous->capacity(), block.capacity());
                insertFreeBlock(*newBlock);
                newBlock->insertBetween(previous, NULL);
                m_last = newBlock;
            }
            
            if (m_first == &block) m_first = block.m_next;
            
            removeFreeBlock(block);
            if (block.m_previous != NULL) block.m_previous->m_next = block.m_next;
            if (block.m_next != NULL) block.m_next->m_previous = block.m_previous;
            delete &block;

            return last;
        }
Exemple #7
0
Fichier : mm.c Projet : YurieCo/hsi
/*	places block for malloc function into free block
		basically changing last byte to 1 in header, so that
		block is marked as not empty, if free Block is >  tha what we need to allocate,
		also split free bloc, etc.
		*/
static void * placeBlock(BlockInfo * freeBlock, size_t reqSize, size_t precedingBlockUseTag)
{
	size_t sizeFree;
	BlockInfo * restOfFreeBlock;
	
	sizeFree = (size_t)SIZE( freeBlock->sizeAndTags ); //gives size without last 3 indicator bits
	removeFreeBlock(freeBlock);
	
	if( (sizeFree - reqSize) > MIN_BLOCK_SIZE )
	{
		freeBlock->sizeAndTags = reqSize | precedingBlockUseTag;
		//printf("Ex-Free block after allocation 0x%x %d 0x%x 0x%x\n", 
		//			(int*)freeBlock, (int)freeBlock->sizeAndTags, (int*)freeBlock->next, (int*)freeBlock->prev);
		restOfFreeBlock = POINTER_ADD( freeBlock, reqSize );
		restOfFreeBlock->sizeAndTags = ((sizeFree-reqSize) | TAG_PRECEDING_USED) & (~TAG_USED);
		
		//Updates the boundary tag
		*((int*)POINTER_ADD(freeBlock, (reqSize-WORD_SIZE))) = reqSize;
		*((int*)POINTER_ADD(freeBlock, (sizeFree-WORD_SIZE))) = sizeFree-reqSize;
		
		insertFreeBlock(restOfFreeBlock);		
		//printf("Rest of free block after allocation 0x%x %d 0x%x 0x%x\n", 
		//		(int*)restOfFreeBlock, (int)restOfFreeBlock->sizeAndTags, (int*)restOfFreeBlock->next, (int*)restOfFreeBlock->prev);
	}
	else
	{
		//freeBlock->sizeAndTags = sizeFree | TAG_USED;
		// Updates the following blocks preceding used and the boundary tag
		*((int*)POINTER_ADD(freeBlock, (sizeFree-WORD_SIZE))) = sizeFree;
		restOfFreeBlock = (BlockInfo*)POINTER_ADD(freeBlock, sizeFree);
		restOfFreeBlock->sizeAndTags = restOfFreeBlock->sizeAndTags | TAG_PRECEDING_USED;		
	}
	
	freeBlock->sizeAndTags |= TAG_USED;
	freeBlock->sizeAndTags |= precedingBlockUseTag;
}
/* Allocate a block of size size and return a pointer to it. */
void* mm_malloc (size_t size) {
  size_t reqSize;
  BlockInfo * ptrFreeBlock = NULL;
  size_t blockSize;
  size_t precedingBlockUseTag;

  // 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!
  size += WORD_SIZE;
  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);
  }

  // Implement mm_malloc.  You can change or remove any of the above
  // code.  It is included as a suggestion of where to start.
  // You will want to replace this return statement...
 
  // Search the free list for a fit
  ptrFreeBlock = searchFreeList(reqSize);
 
  // No fit found. Get more memory
  if (ptrFreeBlock == NULL) {
    requestMoreSpace(reqSize);
    ptrFreeBlock = searchFreeList(reqSize);
  }

  // place the acquired block and split excessive part as needed
  removeFreeBlock(ptrFreeBlock);

  blockSize = SIZE(ptrFreeBlock->sizeAndTags);
  precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED;

  if (blockSize - reqSize >= MIN_BLOCK_SIZE) {
    size_t newFreeBlockSize = blockSize - reqSize;

    BlockInfo *newPtrFreeBlock = (BlockInfo*)POINTER_ADD(ptrFreeBlock, reqSize);
    newPtrFreeBlock->sizeAndTags = newFreeBlockSize | TAG_PRECEDING_USED;	// !TAG_USED

    // update the boundary tag
    *((size_t*)POINTER_ADD(newPtrFreeBlock, newFreeBlockSize - WORD_SIZE)) = 
            newFreeBlockSize | TAG_PRECEDING_USED;	// !TAG_USED
    // insert the new free block into free list
    insertFreeBlock(newPtrFreeBlock);

    blockSize = reqSize;
  } else {
    // do not need to split the block, but need to update the status of following block
    BlockInfo *followingBlock = (BlockInfo*)POINTER_ADD(ptrFreeBlock, blockSize);
    size_t followingBlockSize = SIZE(followingBlock->sizeAndTags);
    size_t followingBlockUsed = followingBlock->sizeAndTags & TAG_USED;
    followingBlock->sizeAndTags = followingBlockSize | TAG_PRECEDING_USED | followingBlockUsed;
    if (followingBlockUsed != TAG_USED) {
      *((size_t*)POINTER_ADD(followingBlock, followingBlockSize - WORD_SIZE)) = followingBlock->sizeAndTags; 
    }
  }

  ptrFreeBlock->sizeAndTags = blockSize | precedingBlockUseTag | TAG_USED;
  // we do not care about the boundary tag of used block!

  return POINTER_ADD(ptrFreeBlock, WORD_SIZE); 
}
Exemple #9
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;
  size_t blockSize;
  size_t precedingBlockUseTag;
  BlockInfo * nextBlock = NULL;
  BlockInfo * newBlock = 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!
  size += WORD_SIZE;
  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);
  }

  // Implement mm_malloc.  You can change or remove any of the above
  // code.  It is included as a suggestion of where to start.
  // You will want to replace this return statement...
/*
  ptrFreeBlock = searchFreeList(reqSize);
  if( ptrFreeBlock != NULL) {
	  blockSize = SIZE(ptrFreeBlock->sizeAndTags);
	  nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize);
	  nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED;
	  removeFreeBlock(ptrFreeBlock);
	  ptrFreeBlock->sizeAndTags =   ptrFreeBlock->sizeAndTags | TAG_USED;
	  return POINTER_ADD( ptrFreeBlock, WORD_SIZE);
  }
  
  requestMoreSpace(reqSize);
  ptrFreeBlock = searchFreeList(reqSize);
  if( ptrFreeBlock != NULL) {
	   blockSize = SIZE(ptrFreeBlock->sizeAndTags);
	  nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize);
	  nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED;
	  removeFreeBlock(ptrFreeBlock);
	  ptrFreeBlock->sizeAndTags =   ptrFreeBlock->sizeAndTags | TAG_USED; 
	  return POINTER_ADD( ptrFreeBlock, WORD_SIZE);
  }
*/
 ptrFreeBlock = searchFreeList(reqSize);
 if( ptrFreeBlock == NULL){
	 requestMoreSpace(reqSize);
     ptrFreeBlock = searchFreeList(reqSize);
 }
 
 blockSize = SIZE(ptrFreeBlock->sizeAndTags);
 
 if( (blockSize - reqSize) >= MIN_BLOCK_SIZE ){
	precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED;
	ptrFreeBlock->sizeAndTags = reqSize | precedingBlockUseTag | TAG_USED ;
    removeFreeBlock(ptrFreeBlock);
    
    newBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, reqSize);
    newBlock->sizeAndTags = blockSize - reqSize;
    newBlock->sizeAndTags = newBlock->sizeAndTags | TAG_PRECEDING_USED;
    *((size_t*)POINTER_ADD(newBlock, blockSize - reqSize - WORD_SIZE ) ) = newBlock->sizeAndTags;

	insertFreeBlock(newBlock);
 }else{
    nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize);
    nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED;
   
    ptrFreeBlock->sizeAndTags =   ptrFreeBlock->sizeAndTags | TAG_USED;
    removeFreeBlock(ptrFreeBlock);  
 }
 return POINTER_ADD( ptrFreeBlock, WORD_SIZE);
}
Exemple #10
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;
  BlockInfo * splitBlock;
  size_t blockSize;
  size_t precedingBlockUseTag;

  // 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!
  size += WORD_SIZE;
  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);
  }

  // Implement mm_malloc.  You can change or remove any of the above
  // code.  It is included as a suggestion of where to start.
  // You will want to replace this return statement...

  // find free block of reqSize
  ptrFreeBlock = searchFreeList(reqSize);
  while ( ptrFreeBlock == NULL ) {
    requestMoreSpace(1 << 14);
    ptrFreeBlock = searchFreeList(reqSize);
  }
  // check free block size vs reqSize vs alignment requirements,
  // split if necessary. If split, reformat newly created free
  // block (add header, set bits, add footer).
  blockSize = SIZE(ptrFreeBlock->sizeAndTags);
  if ( blockSize - reqSize >= MIN_BLOCK_SIZE ) {
    // Split, set size and tags of new block
    splitBlock = (BlockInfo*) POINTER_ADD(ptrFreeBlock, reqSize);
    blockSize -= reqSize;
    splitBlock->sizeAndTags = blockSize | TAG_PRECEDING_USED;
    splitBlock->sizeAndTags &= ~0 << 1; // turn off use bit - preserve others
    
    // set footer equal to header. Current ptr + blockSize - one word = boundary
    // tag of current block (word prior to start of next block)
    *((size_t*) POINTER_ADD(splitBlock, blockSize- WORD_SIZE))= 
      splitBlock->sizeAndTags;
    insertFreeBlock(splitBlock);
    // set size of ptrFreeBlock to exclude size of newBlock
    blockSize = reqSize;
  } else { // if we didnt split, set the next block's preceding tag to 1
    *((size_t*) POINTER_ADD(ptrFreeBlock, SIZE(ptrFreeBlock->sizeAndTags))) |= 
			   TAG_PRECEDING_USED;
  }
  removeFreeBlock(ptrFreeBlock);

  precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED;
  // if the preceding block is used as well, set lower two bits. Else, set only
  // used bit.
  if ( precedingBlockUseTag ) {
    ptrFreeBlock->sizeAndTags = blockSize | (TAG_PRECEDING_USED + TAG_USED);
  } else {
    ptrFreeBlock->sizeAndTags = blockSize | TAG_USED;
  }

  // return pointer to block (beginning of payload)
  // if null, return null. else return 8 after start of block (ie skip header,
  // return ptr to payload region)
  if ( ptrFreeBlock == NULL) { return NULL; }
  else { return (void*) POINTER_ADD(ptrFreeBlock, WORD_SIZE); }
 }