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; }
//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; }
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; }
/* 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); } }
/** * @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]); }
//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; }
/********************************************************** * 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; }
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; }
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); }
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; }
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 ); } }
//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; }
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); } }
// 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; }
/********************************************************** * 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; }
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; }