Files
chat_rebot-connect-with-one…/c/memctl/memctl.c

144 lines
3.8 KiB
C

#include "memctl.h"
#include <stdio.h>
#include <stdlib.h>
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;i<target;i++)//分配内存
{
if(self->blocks[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,FREE);
}
atomic_fetch_add(&self->poolsize,size);
int log = atomic_load(&self->logbuf)+size/2;
atomic_store(&self->logbuf,log);//重新划定日志区
return 0;
}
mem_block *GetBlock(mem_ctl* self,int type)
{
int status = 0;
int sp=0,start = 0;
atomic_int *id;
//模式判断
if(type == LOGMOD)
{
id = &self->Loglast_loc;
sp = self->poolsize;
start = self->logbuf;
}
else
{
id = &self->Commenlast_loc;
sp = self->logbuf;
}
int i = atomic_load(id);
for(status;status<CYCLE_NUM;status++)//最多扫描轮次
{
//获取空闲块
for(i;i<sp;i++)
{
if(atomic_fetch_sub(&self->blocks[i].condition,1) == FREE)
{
atomic_fetch_sub(&self->blocks[i].condition,1);
return &self->blocks[i];
}
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,mem_block *block)
{
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] == 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;i<MAX_MEM_SIZE;i++)
{
self->blocks[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;i++;i<MAX_MEM_SIZE)
{
if(self->blocks[i].location!=NULL)
free(self->blocks[i].location);
}
}