예제 #1
0
RingBufferBlock* RingBuffer::searchFreeBlock(int size)
{
	int alignLength = ALIGN(sizeof(struct RingBufferBlock) + size);
	int freeSpace = 0;

	// 从head开始依次往后查找空闲block,直到拼接起来的空闲block长度大于传入的size
	struct RingBufferBlock *block = getHead();
	do {
		// 如果该块当前仍在被使用,则中止搜索
		if (block->m_link != NULL && block->m_length >= sizeof(struct RingBufferBlock)) {
			return NULL;
		}

		freeSpace += ALIGN(block->m_length) + sizeof(RingBufferBlock);

		// 检测长度是否已足够分配
		if (freeSpace > alignLength + sizeof(RingBufferBlock)) {
			// 将找到的这几块空闲block切割为2块block,并返回第一块block的地址
			return splitBlock(freeSpace , size);
		}

		block = getNextBlock(block);
	} while(block);

	return NULL;
}
예제 #2
0
파일: mm.c 프로젝트: MrLoh/TI3-Uebungen
//versucht einen Speicherbereich mit <byteCount> vielen Bytes zu reservieren
//Falls dies nicht gelingt wird ein NULL (0) Pointer zurueckgeliefert
void* my_malloc(int byteCount)
{
    if(!b_initialized)
        initialize();
    //Wenn der insgesamt verfuegbare Speicherplatz kleiner ist
    //als der angeforderte, koennen wir gleich aufhoeren!
    if(byteCount > get_free_space())
        return(NULL);

    //SUCHE NACH EINEM GEEIGNETEN FREIEN SPEICHERBLOCK, MIT MEHR ALS <byteCount>
    //VIELEN BYTES
    memoryBlock* block = head;
    while(block != NULL)
    {
        if(block->dataLength > byteCount && block->state == not_allocated)
            goto allocate_memory;
        block = block->nextBlock;
    }
    // FALLS ES KEIN PASSENDES ELEMENT GIBT, GEBEN WIR NULL ZURÜCK.
    return(NULL);

    //Der Knoten block hat genuegend Speicherplatz
    allocate_memory:
        // UNTERTEILUNG DIESES BLOCKS, SO DASS NICHT UNNÖTIG VIEL SPEICHERPLATZ VERBRAUCHT WIRD
        // UND RÜCKGABE DES ZEIGERS AUF DEN ZU BENUTZENDEN SPEICHERBEREICH
        return splitBlock(block, byteCount)->data;
}
예제 #3
0
	void * realloc(void * ptr, size_t size)
	{
		char * charPtr = static_cast<char *>(ptr);
		Block & block = blocks.at(charPtr);
		Block & next = nextBlock(charPtr);

		/* There is enough place ahead of the current block */
		if(block.size == size)
		{

		}
		else if(block.size > size)
		{
			splitBlock(block, size);
			Block & rest = blocks.at(block.ptr + size);
			markBlockFree(rest);
			if(next.free)
			{
				resizeBlock(rest, rest.size + next.size);
				removeBlock(next);
			}
		}
		else if(next.free && block.size + next.size >= size)
		{
			splitBlock(next, size-block.size);
			removeBlock(next);
			resizeBlock(block, size);
		}
		else
		{	
			void * newPtr = alloc(size);
			if(newPtr != NULL)
			{
				memcpy(newPtr, ptr, block.size);
				free(ptr);
				ptr = newPtr;
			}
		}


		#ifdef SELFTEST
		selfTest();
		#endif

		return ptr;
	}
예제 #4
0
파일: malnSet.c 프로젝트: dentearl/mafJoin
/* add a mafAli to the set */
static void addMafAli(struct malnSet *malnSet, struct mafAli *mafAli, int maxInputBlkWidth, double defaultBranchLength, struct Genome *treelessRootGenome) {
    struct malnBlk *blk = mafAliToMAlnBlk(malnSet->genomes, mafAli, defaultBranchLength, treelessRootGenome);
    if (blk->alnWidth < maxInputBlkWidth) {
        malnSet_addBlk(malnSet, blk);
    } else {
        splitBlock(malnSet, maxInputBlkWidth, blk);
        malnBlk_destruct(blk);
    }
}
예제 #5
0
/**
 * @brief  Allocate a variable sized object on the memory pool.
 * @param  pool The pool to allocate from.
 * @param  size The size of the object to allocate.
 * @return A valid address on success, NULL on failure.
 */
void *lpx_mempool_variable_alloc(lpx_mempool_variable_t *pool, long size)
{
    void *candidateBlock = NULL;
    int unlockNeeded = 0;
    
    if (UNLIKELY(pool == NULL)) {
        return NULL;
    }

    // Lock the mutex if needed.
    if (pool->poolMutex != NULL) {
        if (0 != pthread_mutex_lock(pool->poolMutex)) {
	    return NULL;
	}
	unlockNeeded = 1;
    }

    // First off, adjust the size to accomodate the metadata.
    size += MEMPOOL_PER_BLOCK_OVERHEAD;
    if (size < 3 * sizeof(long)) {
        // Because this should be linkable back into the list.
	size += 3 * sizeof(long);
    }

    // Find the first fit block from the free list.
    candidateBlock = findFirstFit(pool, size);
    if (candidateBlock == NULL) {
        if (unlockNeeded) {
	    pthread_mutex_unlock(pool->poolMutex);
	}
        return NULL;
    }
    
    // Split the block and re-link the free list.
    candidateBlock = splitBlock(pool, candidateBlock, &size);
    if (candidateBlock == NULL) {
        if (unlockNeeded) {
	    pthread_mutex_lock(pool->poolMutex);
	}
	return NULL;
    }

    // Prep the block for return.
    ((long *)candidateBlock)[0] = (long)pool;
    ((long *)candidateBlock)[1] = size;

    // Unlock the mutex if needed.
    if (pool->poolMutex != NULL) {
        if (0 != pthread_mutex_unlock(pool->poolMutex)) {
	    return NULL;
	}
    }

    // &candidateBlock[2] is the start of the user memory block.
    return &(((long *)candidateBlock)[2]);
}
예제 #6
0
파일: mm.c 프로젝트: Sanuye/TI3-C
//versucht einen Speicherbereich mit <byteCount> vielen Bytes zu reservieren
//Falls dies nicht gelingt wird ein NULL (0) Pointer zurueckgeliefert
void* my_malloc(int byteCount)
{
	if(!b_initialized)
	{
		initialize();
	}
	//DEBUG
	//printf("mAllocating..%d\n",byteCount);
	//Wenn der insgesamt verfuegbare Speicherplatz kleiner ist
	//als der angeforderte, koennen wir gleich aufhoeren!
	if(byteCount > get_free_space())
	{
		return(NULL);
	}
	memoryBlock *block = head;
	//TODO - WIP - seems finished - needs testing - works
	//SUCHE NACH EINEM GEEIGNETEN FREIEN SPEICHERBLOCK, MIT MEHR ALS <byteCount>
	//VIELEN BYTES
	// + memoryBlockHeaderSize ? nvm .. bei einer anforderung die die gesamte blockgroesse benoetigt muss kein header fuer einen splitBlock beruecksichtigt werden
	memoryBlock *return_blockData = NULL;
	while(block != NULL)
	{
		if(block->state == not_allocated){
			if(block->dataLength >= byteCount){
				if(return_blockData == NULL){
					return_blockData = block;
				}else{
					if(return_blockData->dataLength > block->dataLength){
						return_blockData = block;
					}
				}
			}
		}
		block = block->nextBlock;
	}
	// FALLS ES KEIN PASSENDES ELEMENT GIBT, GEBEN WIR NULL ZURUECK.
	if(return_blockData == NULL){
		return NULL;
	}
	// Der Knoten block hat genuegend Speicherplatz
	//if((return_blockData->dataLength) >= (byteCount+memoryBlockHeaderSize)){
		//UNTERTEILUNG DIESES BLOCKS, SO DASS NICHT UNNOETIG VIEL SPEICHERPLATZ VERBRAUCHT WIRD#
		splitBlock(return_blockData,byteCount);
	//}else{
		//ERROR
		//printf("Nicht genug Platz fuer Speicher %d UND header %d in %d",byteCount,memoryBlockHeaderSize,return_blockData->dataLength);

		//return NULL;
	//}
	// UND MARKIERE DIESEN BLOCK
	return_blockData->state = allocated;
	//DEBUG
	//printf("mAllocated!\n");
	//RueCKGABE DES ZEIGERS AUF DEN ZU BENUTZENDEN SPEICHERBEREICH
	return return_blockData->data;
}
예제 #7
0
/**********************************************************
 * mm_malloc
 * Allocate a block of size bytes.
 * The type of search is determined by find_fit
 * The decision of splitting is determined by spiltBlock
 * If no block satisfies the request, the heap is extended
 **********************************************************/
void *mm_malloc(size_t size) {

    size_t asize; /* adjusted block size */
    size_t extendsize; /* amount to extend heap if no fit */
    char * bp;

    /* Ignore spurious requests */
    if (size == 0)
        return NULL;

    /* Adjust block size to include overhead and alignment reqs. */
    if (size <= DSIZE)
        asize = 2 * DSIZE;
    else
        asize = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE);

    /* Search the free list for a fit */
    if ((bp = find_fit(asize)) != NULL) {
        //remove from the free list
        removeFromFreeList(bp);

        //break the block into smaller one if possible
        bp = splitBlock(bp, asize);
        size_t bsize = GET_SIZE(HDRP(bp));

        //place the block 
        setBlockHeaderFooter(bp, bsize, 1);
        return bp;
    }

    /* No fit found. Get more memory and place the block */

    //Increasing chunksize by 16B gives huge improvment in binary test case.
    //we incease 16 for the reason that it matches size of header and footer
    extendsize = MAX(asize, CHUNKSIZE + 16);

    if ((bp = extend_heap(extendsize / WSIZE)) == NULL)
        return NULL;

    splitBlock(bp, asize);
    place(bp, asize);
    return bp;
}
예제 #8
0
void* sf_malloc(size_t size){
	if(size < 0x1 || size > 0x100000000) return NULL; /* invalid request size */

	if(start == end) init_heapSpace(); /* no call has been made to request heap space, do so here */

	uintptr_t *cursor = (uintptr_t *) NULL_POINTER;

restart_search: /* kind of like the cache if there's no space big enough(miss), get that space and tell you to ask me again */
	cursor = (uintptr_t*) head;

	uintptr_t allocate_size = 0;
	if(size < 16) 
		allocate_size = 16;
	else if (size % 8 == 0) 
		allocate_size = (uintptr_t) size;
	else 
		allocate_size =(uintptr_t) (size + (8 - (size % 8)));

	if((allocate_size / 8) % 2 != 0) allocate_size += 8;

	uintptr_t *result = (uintptr_t*) NULL_POINTER;

	if(cursor != (uintptr_t *)NULL_POINTER){
		while(get_loadSize(cursor) < allocate_size && (uintptr_t) *(cursor + 1) != NULL_POINTER)
		cursor = (uintptr_t *) *(cursor + 1); /* cursor = cursor.getNext(); */

		uintptr_t loadSize = get_loadSize(cursor);

		/* if the request fits and there is space to split */
		if(loadSize > (allocate_size + 48)){
			uintptr_t **ptr = &cursor;
			splitBlock(ptr, size, allocate_size, loadSize); 
			result = cursor + 1;
		}
		else if(loadSize >= allocate_size){
			uintptr_t **ptr = &cursor;
			allocateBlock(ptr, size, allocate_size);
			result = cursor + 1;
		}else if(loadSize < allocate_size){
			addHeapSpace(allocate_size);
			goto restart_search;
		}
	}
	/* could not find a space big enough to hold the requested size */
	else {
		addHeapSpace(allocate_size);
		goto restart_search;
	}

	return result;
}
예제 #9
0
	void * alloc(size_t size)
	{
	    char * ptr = findPtrForSize(size);
	    if(ptr != NULL)
	    {
	    	splitBlock(blocks.at(ptr), size);
	    	markBlockBusy(blocks.at(ptr));
	    }

	    #ifdef SELFTEST
	    selfTest();
	    #endif

	    return static_cast<void *>(ptr);
	}
예제 #10
0
파일: mm_alloc.c 프로젝트: Zienhleh/hw3
struct nca* Free(struct nca *prev, size_t size){	
	struct nca *thisnca = zee;	

	while (true){	
		if (!thisnca){	
			return nca2(prev ,size);
		}
		if (thisnca&&thisnca->free && (thisnca->size)>=size){	
			thisnca=splitBlock(thisnca,size);
			thisnca->free=false;
			return thisnca;	
		}
		prev = thisnca; 
		thisnca = thisnca->next;	
	}
	return 0;	
}
예제 #11
0
static void buildNewStatusString( int block, int id )
{
    char    *mod;

    mod = findBlockString( block );

    switch( id ) {
    case SS_SPLIT:
        splitBlock( block, mod );
        break;
    case SS_DESTROY:
        destroyBlock( block, mod );
        break;
    case SS_DEFAULTS:
        buildDefaults();
        break;
    default:
        buildNewItem( mod, id );
    }
}
예제 #12
0
파일: mm.c 프로젝트: pandemie/WS10TI3
//versucht einen Speicherbereich mit <byteCount> vielen Bytes zu reservieren
//Falls dies nicht gelingt wird ein NULL (0) Pointer zurueckgeliefert
void* my_malloc(int byteCount)
{
    if(!b_initialized)
    {
        initialize();
    }
    //Wenn der insgesamt verfuegbare Speicherplatz kleiner ist
    //als der angeforderte, koennen wir gleich aufhoeren!
    if(byteCount > get_free_space())
    {
        return(NULL);
    }
    //TODO - DONE
    //SUCHE NACH EINEM GEEIGNETEN FREIEN SPEICHERBLOCK, MIT MEHR ALS <byteCount>
    //VIELEN BYTES
    memoryBlock* block = head;
    while ( 1 ){
        // Keine geeigneter Block gefunden
        if ( block == NULL ){
            // jetzt m�sste man anfangen zu defragmentieren
            // geht nur leider ohne virtuelle Speicheradressen nicht,
            // da sonst die von uns zur�ckgegebenen Pointer ung�ltig werden
            return NULL;
        }

        // Einen Block gefunden, der gro� genug ist
        if ( block->state == not_allocated && block->dataLength >= byteCount ){
            break;
        }

        block = block->nextBlock;
    }

    //UNTERTEILUNG DIESES BLOCKS, SO DASS NICHT UNN�TIG VIEL SPEICHERPLATZ VERBRAUCHT WIRD
    block = splitBlock ( block, byteCount );

    //R�CKGABE DES ZEIGERS AUF DEN ZU BENUTZENDEN SPEICHERBEREICH
    block->state = allocated;
    return (void *) block->data;
}
예제 #13
0
static void splitBlock(int splitIdx, int neededIdx, metadata_t *currBlock) {
	// base condition
	if (splitIdx == neededIdx) {
		return;
	} else {
		// if there is a buddy, split the first one
		if (currBlock->next != NULL) {
			metadata_t *temp = currBlock->next;
			// remove the splited block
			currBlock->prev = NULL;
			currBlock->next = NULL;
			currBlock->size /= 2;
			currBlock->in_use = 0;
			// next block becomes the head
			temp->prev = NULL;
			freelist[splitIdx] = temp;
		} else {
            // if there is not a buddy, split it directly
            currBlock->prev = NULL;
            currBlock->size /= 2;
            currBlock->in_use = 0;
			freelist[splitIdx] = NULL;
		}
		// the addresses of two new blocks
        splitIdx--;
        freelist[splitIdx] = currBlock;

		metadata_t *newBlock = (metadata_t *) ((char *) currBlock + currBlock->size);
		newBlock->size = currBlock->size;
		newBlock->in_use = 0;
		newBlock->next = NULL;
		newBlock->prev = currBlock;
        currBlock->next = newBlock;
        
		// recursion occurs here!
		splitBlock(splitIdx, neededIdx, currBlock);
	}
}
예제 #14
0
파일: mm.c 프로젝트: Peabrain/studium
// Versucht einen Speicherbereich mit <byteCount> vielen Bytes zu reservieren
// Falls dies nicht gelingt wird ein NULL (0) Pointer zurueckgeliefert
void* my_malloc(int byteCount)
{
	if(!b_initialized)
	{
		initialize();
	}
	// Wenn der insgesamt verfuegbare Speicherplatz kleiner ist
	// als der angeforderte, koennen wir gleich aufhoeren!
	if(byteCount > get_free_space())
	{
		return(NULL);
	}
	memoryBlock *block = head;
	// TODO
	// SUCHE NACH EINEM GEEIGNETEN FREIEN SPEICHERBLOCK, MIT MEHR ALS <byteCount>
	// VIELEN BYTES
	//

	do
	{
		if(block->state == not_allocated && block->dataSize >= byteCount + memoryBlockHeaderSize) break;
		block = block->nextMemBlock;
	}
	while(block != 0);

	// FALLS ES KEIN PASSENDES ELEMENT GIBT, GEBEN WIR NULL ZURUECK.
	if(block == 0) return 0;

	// Der Knoten block hat genuegend Speicherplatz

	// UNTERTEILUNG DIESES BLOCKS, SO DASS NICHT UNNOETIG VIEL SPEICHERPLATZ VERBRAUCHT WIRD
	// UND MARKIERE DIESEN BLOCK
	block = splitBlock(block,byteCount);
	block->state = allocated;

	// RUECKGABE DES ZEIGERS AUF DEN ZU BENUTZENDEN SPEICHERBEREICH
	return block->data;
}
예제 #15
0
/**********************************************************
 * mm_realloc
 * Deals with a few cases:
 * 1. if the realloc size is smaller than current size
 * we split the current block and then put the extra part
 * to free list
 * 2. if the next block of the current block is freed, we check if
 * merge these two blocks can lead to a fit block for realloc
 * 3. if the current block is at the end of heap,
 * we just increase the heap by the required amount and then merge
 * that amount into that block
 * 4. if the new size is same as old size we do nothing
 * 5. if the new size is 0, same as free
 * 6. else we malloc a new block and then copy the data from old block 
 *********************************************************/
void *mm_realloc(void *ptr, size_t size) {
    /* If size == 0 then this is just free, and we return NULL. */
    //case 5
    if (size == 0) {
        mm_free(ptr);
        return NULL;
    }
    /* If oldptr is NULL, then this is just malloc. */
    if (ptr == NULL)
        return (mm_malloc(size));

    void *oldptr = ptr;
    void *newptr;
    size_t copySize;
    size_t oldSize = GET_SIZE(HDRP(oldptr));
    size_t asize;

    /* Adjust block size to include overhead and alignment reqs. */
    if (size <= DSIZE)
        asize = 2 * DSIZE;
    else
        asize = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE);

    //case 4 (see above)
    if (oldSize == asize) {
        return ptr;
    }        //case 1
    else if (oldSize > asize) {
        void* newptr = splitBlock(ptr, asize);
        place(newptr, asize);
        return newptr;
    }        //case 2
    else if (GET_SIZE(HDRP(NEXT_BLKP(ptr))) != 0) {

        if (GET_ALLOC(HDRP(NEXT_BLKP(ptr))) == 0) {
            //get the merge size after merge with next block
            size_t msize = oldSize + GET_SIZE(HDRP(NEXT_BLKP(ptr)));
            if (msize >= asize) {
                //coalesce next block with current block
                removeFromFreeList(NEXT_BLKP(ptr));
                PUT(HDRP(ptr), PACK(msize, 0));
                PUT(FTRP(ptr), PACK(msize, 0));

                //split block if there is extra space
                void* newptr = splitBlock(ptr, asize);
                place(newptr, asize);
                return newptr;
            }
        }
    }        //case 3
    else if (GET_SIZE(HDRP(NEXT_BLKP(ptr))) == 0) {
        //new size larger than old size and next block is epilogue
        //we can extend the heap and then coalesce

        size_t esize = asize - oldSize; //calculate sufficient space to extend
        //extend heap by the sufficient amount
        void* ebp = extend_heap(esize / WSIZE);

        if (ebp != NULL) {
            //coalesce the extend space into current block
            PUT(HDRP(ptr), PACK(asize, 1));
            PUT(FTRP(ptr), PACK(asize, 1));
            return ptr;
        }
    }

    //case 6
    newptr = mm_malloc(size);
    if (newptr == NULL)
        return NULL;

    /* Copy the old data. */
    copySize = GET_SIZE(HDRP(oldptr));

    memcpy(newptr, oldptr, copySize);
    mm_free(oldptr);
    return newptr;
}
예제 #16
0
void* my_malloc(size_t size)
{
  	// calculate the needed size
	int total_size = size + sizeof(metadata_t);

	// if the requested size is beyond our largest block size
	if (total_size > SBRK_SIZE) {
		ERRNO = SINGLE_REQUEST_TOO_LARGE;
		return NULL;
	}
	// set up the heap if it is uninitialized
	if (!heap) {
		setupHeap();
		if (ERRNO == OUT_OF_MEMORY) {
			return NULL;
		}
	}
	// get index of the free list to allocate memory to the user
	int idx = getIdx(total_size);
	metadata_t *allocBlock = NULL;
	// if we have a memory block to allocate
	if (freelist[idx] != NULL) {
		// just simply return the first block
		allocBlock = freelist[idx];
		// if there is the next block
		if (allocBlock->next != NULL) {
			allocBlock->next->prev = NULL;
			freelist[idx] = allocBlock->next;
		} else {
			freelist[idx] = NULL;
		}
		// remove this block/
		allocBlock->in_use = 1;
		allocBlock->prev = NULL;
		allocBlock->next = NULL;

		// return the block
		return ((char*)allocBlock + sizeof(metadata_t));
	}
	// if we do not have a memory block to allocate
	// we split the second smallest blocks into blocks of needed size
	int splitIdx = idx + 1;
	while (freelist[splitIdx] == NULL) {
		splitIdx++;
	}
	// if there are no blocks to split
	if (splitIdx == 8) {
		// set up a new heap
		setupHeap();
		if (ERRNO == OUT_OF_MEMORY) {
			return NULL;
		}
	} else { // if a block can be split 
		splitBlock(splitIdx, idx, freelist[splitIdx]); // a recursive function
	}
	// call my_malloc() again to allocate memory
	allocBlock = my_malloc(size);
    // set the error code
    ERRNO = NO_ERROR;

  	return allocBlock;
}