#include "memctl.h" #include #include #include #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - offsetof(type, member))) int extend_pool(mem_ctl* self,int size) { if(self == NULL)//入参检查 { return -1; } int poolsize = atomic_load(&self->poolsize); int target = poolsize +size;//计算目标大小 if(target >MAX_MEM_SIZE) target = MAX_MEM_SIZE;//计算限制 for(int i = poolsize;iblocks[i].location !=NULL)//若存在未释放内存 free(self->blocks[i].location); self->blocks[i].location = malloc(MEM_BLOCK_SIZE); if(self->blocks[i].location == NULL) return target-i;//堆内存不足 atomic_store(&self->blocks[i].condition,MEM_FREE); } atomic_fetch_add(&self->poolsize,size); int log = atomic_load(&self->logbuf)+size/2; atomic_store(&self->logbuf,log);//重新划定日志区 return 0; } void **GetBlock(mem_ctl* self,int type) { int status = 0; int sp=0,start = 0; int id; //模式判断 if(type == LOGMOD) { id = atomic_load(&self->Loglast_loc); sp = atomic_load(&self->poolsize); start = atomic_load(&self->logbuf); if(idCommenlast_loc); sp = atomic_load(&self->logbuf)+1; if(id>sp) id = start; } int i = id; for(status;statusblocks[i].condition,1) == MEM_FREE) { atomic_fetch_sub(&self->blocks[i].condition,1); if(i>self->logbuf) atomic_store(&self->Loglast_loc,i); else atomic_store(&self->Commenlast_loc,i); return &self->blocks[i].location; } else{ atomic_fetch_add(&self->blocks[i].condition,1);//回滚路径 } } i = start; atomic_fetch_add(&self->mem_e_indicator,1); //检查是否需要扩池 if(atomic_fetch_sub(&self->mem_e_indicator,POOL_EXPEND_ID)>POOL_EXPEND_ID) { extend_pool(self,POOL_EXPEND_SIZE); } else{ atomic_fetch_add(&self->mem_e_indicator,POOL_EXPEND_ID); } } return NULL; } int FreeBlock(mem_ctl* self,void** block_p) { mem_block *block; block = container_of(block_p,mem_block,location); if(self == NULL) return -1; if(block == NULL) return -1; if(block < &self->blocks[COMINE_MEM_SIZE])//标准池部分归还 { atomic_fetch_add(&block->condition,2); block = NULL; return 0; } else//扩容池尝试回收 { atomic_fetch_add(&block->condition,1); free(block->location); block->location = NULL; int poolsize = atomic_load(&self->poolsize); if(&self->blocks[poolsize-1] == block) { for(int i = poolsize -1;i>COMINE_MEM_SIZE;i--) { if(atomic_load(&self->blocks[i].condition) == PROCESSING) { poolsize--; } else{ break; } if(poolsize-COMINE_MEM_SIZE%2 == 0) { atomic_fetch_sub(&self->logbuf,1); } } } atomic_store(&self->poolsize,poolsize); } } int init_memctl(mem_ctl *self) { if(self == NULL) return -1; self->poolsize = 0; for(int i =0;iblocks[i].location = NULL; atomic_init(&self->blocks[i].condition,PROCESSING);//初始化池 } extend_pool(self,COMINE_MEM_SIZE);//预分配内存 self->Commenlast_loc = 0; self->logbuf = COMINE_MEM_SIZE/2; self->mem_e_indicator = 0; self->FreeBlock = FreeBlock; self->GetBlock = GetBlock; return 0; } int free_memctl(mem_ctl *self)//清除内存池 { if(self == NULL) return -1; for(int i = 0;iblocks[i].location!=NULL) free(self->blocks[i].location); } return 0; }