void* splitUntil(void* freeBuffer, int bufferSize, int desiredBufferSize) { int newBufferSize = bufferSize/2; // split and get two pointers void* smallerBufferOne = freeBuffer; void* smallerBufferTwo = (void*)((BYTE*) freeBuffer + newBufferSize); // remove from free list removeFromFreeList(freeBuffer, bufferSize); // add later pointer to smaller free list insertIntoFreeList(smallerBufferTwo, newBufferSize); // either return or recursively call function if (newBufferSize == desiredBufferSize) { setBitmap(smallerBufferOne, desiredBufferSize); bufferData_t* bufferData = (bufferData_t*)smallerBufferOne; bufferData->nextFreeBuffer = NULL; bufferData->bufferSize = desiredBufferSize; return smallerBufferOne; } else { return splitUntil(smallerBufferOne, newBufferSize, desiredBufferSize); } }
void kma_free(void* ptr, kma_size_t size) { void* internalPtr = (void*)(((BYTE*) ptr) - sizeof(bufferData_t)); int bufferSize = getAmountOfMemoryToRequest(size); size_t pageNum = getPageNumber(BASEADDR(internalPtr)); // unset bitmap unsetBitmap(internalPtr, bufferSize); // coalesce free buddies coalesceFreeMemory(&internalPtr, &bufferSize); if (bufferSize == PAGESIZE) { // can free page free_page(startOfManagedMemory->pages[pageNum].pageData); // right way would be to shift all pages after this over int pageIndex = pageNum + 1; while (startOfManagedMemory->pages[pageIndex].pageData != NULL) { memcpy((void*)&startOfManagedMemory->pages[pageIndex-1], (void*)&startOfManagedMemory->pages[pageIndex], sizeof(pageControlStruct_t*)); pageIndex = pageIndex + 1; } // so that the last page in list isn't duplicated startOfManagedMemory->pages[pageIndex-1].pageData = NULL; int j; for (j=0; j < BITMAP_SIZE; j++) { startOfManagedMemory->pages[pageIndex-1].bitmap[j] = 0; } } if (onlyControlStructureLeft()) { // everything gone except control structure // free page free_page(startOfManagedMemory->pages[0].pageData); startOfManagedMemory = NULL; return; } if (bufferSize != PAGESIZE) { // insert into free list insertIntoFreeList(internalPtr, bufferSize); } }
/** * @brief Free an object that was allocated on variable sized memory pool. * @param addr The address of the object to free. * @return 0 on success, -1 on failure. */ int lpx_mempool_variable_free(void *addr) { lpx_mempool_variable_t *pool = NULL; long size = 0; long *originalBlock = (long *)addr; if (UNLIKELY(addr == NULL)) { return MEMPOOL_FAILURE; } // Find the pool that this block points to & the size of the block. originalBlock -= 2; pool = (lpx_mempool_variable_t *)originalBlock[0]; size = originalBlock[1]; if (pool->magic != MEMPOOL_VARIABLE_MAGIC) { return MEMPOOL_FAILURE; } // Lock the mutex if needed. if (pool->poolMutex != NULL) { if (0 != pthread_mutex_lock(pool->poolMutex)) { return MEMPOOL_FAILURE; } } // Add the block back into the free list. originalBlock[VPMD_SIZE_OFFSET] = size; insertIntoFreeList(pool, (void *)originalBlock); // Unlock the mutex if needed. if (pool->poolMutex != NULL) { if (0 != pthread_mutex_unlock(pool->poolMutex)) { return MEMPOOL_FAILURE; } } return MEMPOOL_SUCCESS; }