📄 rvmemblock.c
字号:
/*
RvMemBlockMgr
Allocation of 'auxiliary' memory from a pool of memory blocks
Will allocate memory of any required size ( up to block size )
and add a new block if needed.
Memory cannot be freed,but Contract will release all the blocks but one
to the pool
*/
#include <stdio.h>
#include "rvutil.h"
#include "rvtypes.h"
#include "rvmemblock.h"
#include "rvlog.h"
#include "rvdefalloc.h"
#define HEADER_SIZE rvAlign(sizeof(RvMemBlock))
static void LogAllocFail(int size) {
char errmsg[128];
sprintf(errmsg,"rvMemBlockAlloc fail to allocate %d bytes\n",size);
rvLogError(&rvLog,errmsg);
}
static void rvMemBlockInitBlock(RvMemBlock * block,size_t size,RvBool is_def_alloc) {
/* Initialize memory block */
block->cur = (char *)block +HEADER_SIZE;
block->end = (char *)block + size;
block->is_def_alloc = is_def_alloc;
block->next = 0;
}
/* Allocates and initialize a new block, either from pool or using rvDefAlloc */
/* Blocks bigger than pool blocks will be allocated using rvDefAlloc */
/* Mark the block according to how it was allocated */
static RvMemBlock * rvMemBlockNewBlock(RvAlloc* a,size_t size) {
size_t available_size,alloc_size;
RvMemBlock * block;
size_t block_size = (size_t)rvAllocGetMaxSize(a);
/* Size available in the pool block for data */
available_size = block_size-HEADER_SIZE;
if( (size <= available_size) &&
( block = (RvMemBlock*)rvAllocAllocate(a,block_size))!=NULL ) {
rvMemBlockInitBlock(block,block_size,rvFalse);
}
else {
/* If size was too big or mem_pool allocation failed,
allocate from rvDefAlloc */
/* Make allocation size big enough to hold size + header */
alloc_size = rvMax(size+HEADER_SIZE,block_size);
if( (block = (RvMemBlock*)(rvAllocAllocate(&rvDefaultAlloc,alloc_size)))!=NULL )
rvMemBlockInitBlock(block,alloc_size,rvTrue);
}
return block;
}
static void rvMemBlockDestructBlock(RvMemBlockMgr * mem_mgr,RvMemBlock * block) {
if(block->is_def_alloc==rvFalse) {
rvAllocDeallocate(mem_mgr->pool_alloc,rvAllocGetMaxSize(mem_mgr->pool_alloc),block);
}
else {
rvAllocDeallocate(&rvDefaultAlloc,0,block);
}
}
static RvMemBlock * rvMemBlockExpand(RvMemBlockMgr * mem_mgr,size_t size) {
RvMemBlock * cur = mem_mgr->mem_block;
/* Allocate new memory block from pool */
if( !(mem_mgr->mem_block = (RvMemBlock*)rvMemBlockNewBlock(mem_mgr->pool_alloc,size)) ) {
/* If alloc fail, restore pointer and return error */
mem_mgr->mem_block=cur;
return 0;
}
/* Chain last memory block to new one */
cur->next = mem_mgr->mem_block;
return mem_mgr->mem_block;
}
/* Return a buffer of at least size size_
Implements the rvAllocAllocate interface */
void * rvMemBlockAlloc(void * aux_mem_,size_t size_) {
char * buf;
RvMemBlockMgr * mem_mgr = (RvMemBlockMgr *)aux_mem_;
RvMemBlock * mem_block = mem_mgr->mem_block;
size_t size = rvAlign(size_); /* Align to boundaries */
/* If not enough memory in the mem_mgr memory block, add another block to list */
if( mem_block->cur + size > mem_block->end ) {
/* Get new memory block */
if( !(mem_block = rvMemBlockExpand(mem_mgr,size)) ) {
LogAllocFail(size);
return 0;
}
/* new block is still not big enough */
if( mem_block->cur+size > mem_block->end) {
LogAllocFail(size);
return 0;
}
}
buf = mem_block->cur;
/* Move pointer to next free position */
mem_block->cur += size;
return buf;
}
/* Implements the rvAllocDeallocate interface */
void rvMemBlockDealloc(void* pool, size_t size, void* buf) {
return;
}
/* Release all the blocks from the block manager */
void rvMemBlockContract(RvMemBlockMgr * mem_mgr) {
RvMemBlock * head = mem_mgr->head_block;
RvMemBlock * last,* cur = head;
while(cur) {
last = cur;
cur = cur->next;
rvMemBlockDestructBlock(mem_mgr,last);
}
}
RvMemBlock * rvMemBlockInit(RvMemBlockMgr * mem_mgr,RvAlloc* a) {
/*Set the pool allocator */
mem_mgr->pool_alloc = a;
/* Allocate first memory block */
mem_mgr->mem_block = rvMemBlockNewBlock(mem_mgr->pool_alloc,
rvAllocGetMaxSize(a)-HEADER_SIZE);
mem_mgr->head_block = mem_mgr->mem_block;
return mem_mgr->mem_block;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -