memhandle MemoryPool::allocBlock(memaddress size) { #if ACTLOGLEVEL>=LOG_DEBUG_V3 LogObject.uart_send_strln(F("MemoryPool::allocBlock(memaddress size) DEBUG_V3:Function started")); #endif if (size==0) { #if ACTLOGLEVEL>=LOG_WARNING LogObject.uart_send_strln(F("MemoryPool::allocBlock(memaddress size) WARNING: Called 0 size")); #endif return NOBLOCK; } memblock* best = NULL; memhandle cur = POOLSTART; memblock* block = &blocks[POOLSTART]; memaddress bestsize = MEMPOOL_SIZE + 1; do { memhandle next = block->nextblock; memaddress freesize = ( next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) - block->begin - block->size; if (freesize == size) { best = &blocks[cur]; goto found; } if (freesize > size && freesize < bestsize) { bestsize = freesize; best = &blocks[cur]; } if (next == NOBLOCK) { if (best) goto found; else goto collect; } block = &blocks[next]; cur = next; } while (true); collect: { cur = POOLSTART; block = &blocks[POOLSTART]; memhandle next; while ((next = block->nextblock) != NOBLOCK) { memaddress dest = block->begin + block->size; memblock* nextblock = &blocks[next]; memaddress* src = &nextblock->begin; if (dest != *src) { #ifdef MEMPOOL_MEMBLOCK_MV MEMPOOL_MEMBLOCK_MV(dest,*src,nextblock->size); #endif *src = dest; } block = nextblock; } if (blocks[POOLSTART].begin + MEMPOOL_SIZE - block->begin - block->size >= size) best = block; else goto notfound; } found: { block = &blocks[POOLOFFSET]; for (cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++) { if (block->size) { block++; continue; } memaddress address = best->begin + best->size; #ifdef MEMBLOCK_ALLOC MEMBLOCK_ALLOC(address,size); #endif block->begin = address; block->size = size; block->nextblock = best->nextblock; best->nextblock = cur; #if ACTLOGLEVEL>=LOG_DEBUG_V3 LogObject.uart_send_str(F("MemoryPool::allocBlock(memaddress size) DEBUG_V3:Allocated ")); LogObject.uart_send_dec(size); LogObject.uart_send_str(F("byte to block:")); LogObject.uart_send_decln(cur); #endif return cur; } } notfound: #if ACTLOGLEVEL>=LOG_ERR LogObject.uart_send_strln(F("MemoryPool::allocBlock(memaddress size) ERROR:Failed to allocate memory for packet")); #endif return NOBLOCK; }
memhandle MemoryPool::allocBlock(memaddress size) { memblock* best = NULL; memhandle cur = POOLSTART; memblock* block = &blocks[POOLSTART]; memaddress bestsize = MEMPOOL_SIZE + 1; do { memhandle next = block->nextblock; memaddress freesize = ( next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) - block->begin - block->size; if (freesize == size) { best = &blocks[cur]; goto found; } if (freesize > size && freesize < bestsize) { bestsize = freesize; best = &blocks[cur]; } if (next == NOBLOCK) { if (best) goto found; else goto collect; } block = &blocks[next]; cur = next; } while (true); collect: { cur = POOLSTART; block = &blocks[POOLSTART]; memhandle next; while ((next = block->nextblock) != NOBLOCK) { memaddress dest = block->begin + block->size; memblock* nextblock = &blocks[next]; memaddress* src = &nextblock->begin; if (dest != *src) { #ifdef MEMPOOL_MEMBLOCK_MV MEMPOOL_MEMBLOCK_MV(dest,*src,nextblock->size); #endif *src = dest; } block = nextblock; } if (blocks[POOLSTART].begin + MEMPOOL_SIZE - block->begin - block->size >= size) best = block; else goto notfound; } found: { block = &blocks[POOLOFFSET]; for (cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++) { if (block->size) { block++; continue; } memaddress address = best->begin + best->size; #ifdef MEMBLOCK_ALLOC MEMBLOCK_ALLOC(address,size); #endif block->begin = address; block->size = size; block->nextblock = best->nextblock; best->nextblock = cur; return cur; } } notfound: return NOBLOCK; }