📄 mem.c
字号:
_ControlToSystem();
Enlock();
#if WAIT_QUEUE_ALLOC_MODE
task_suspend->queue_ptr=WaitQueueFreeList;
WaitQueueFreeList=task_suspend;
#endif
if (task_suspend->mem_return_pointer==NULL){
Unlock();
return(ERR_TIMEOUT);
}
if(pool_ptr==NULL){
Unlock();
return(ERR_POOL_DELETED);
}
buf=(UNSIGNED *)(task_suspend->mem_return_pointer);
*buf++=pool_id;
*return_pointer=buf;
pool_ptr->tasks_waiting--;
DelList(&(void *)(pool_ptr->task_wait_header),task_suspend);
Unlock();
return (OK);
}
else{
UnProtect(pool_ptr);
return(ERR_NO_MEMORY);
}
}
/*
*********************************************************************************************************
* 释放先前分配的一个分区到其存储池,若有任务在存储池上等待分配,则释放给等待队列上的某个任务
*********************************************************************************************************
*/
STATUS FreeBuff(void *memory)
{
STATUS status;
SIGNED pool_id;
MEM_MCB *pool_ptr;
TASK_TCB *task_ptr;
SIGNED i;
if (memory== NULL ) /* Not allowed to delete idle pool */
return (ERR_INVALID_POINTER);
pool_id=*((SIGNED *)memory-1);
if (pool_id<0 || pool_id >=MAX_POOL_NUM) { /* Not allowed to delete idle task */
return (ERR_INVALID_POOL);
}
pool_ptr=MemPoolTable[pool_id];
if((INT8U *)memory<pool_ptr->start_address || ((INT8U *)memory+pool_ptr->partition_size)>(pool_ptr->start_address+pool_ptr->pool_size))
return (ERR_INVALID_POINTER);
#if DEBUG
DebugLog(FREE_BUFF,pool_id);//在日志中记录操作,时间等信息
#endif
DoProtect(pool_ptr);
if(pool_ptr->task_wait_header){
task_ptr=(pool_ptr->task_wait_header)->task_ptr;
pool_ptr->task_wait_header->mem_return_pointer=memory;
status=_ResumeTask(task_ptr,EVENT_SUSPEND);
if (status==TRUE)
_ControlToSystem();
UnProtect(pool_ptr);
return(OK);
}
else{
(pool_ptr->availables)++;
--pool_ptr->ref_count;
((struct BLOCK_STRUCT *)memory)->block_size=pool_ptr->partition_size;
((struct BLOCK_STRUCT *)memory)->next=pool_ptr->available_header;
pool_ptr->available_header=memory;
UnProtect(pool_ptr);
return (OK);
}
}
/*
*********************************************************************************************************
* 释放先前分配的一个存储块给等待队列上的任务使用
*********************************************************************************************************
*/
STATUS _FreeTask(MEM_MCB *pool_ptr,void **free_memory,INT32U *size)
{
STATUS status,oldstatus;
TASK_TCB *task_ptr;
WAIT_QUEUE *suspend_list;
ULONG request_size;
oldstatus=FALSE;
suspend_list=(WAIT_QUEUE *)(pool_ptr->task_wait_header);
if (suspend_list){
do {
request_size=suspend_list->mem_request_size;
if ((*size) >= request_size){
task_ptr=suspend_list->task_ptr;
suspend_list->mem_return_pointer=*free_memory;
status=_ResumeTask(task_ptr,EVENT_SUSPEND);
if (status==TRUE)
oldstatus=status;
*size=*size-request_size;
(*free_memory)=(INT8U *)(*free_memory)+request_size;
if (*size==0)
break;
}//end if
suspend_list=(WAIT_QUEUE *)(suspend_list->next);
}while(suspend_list!=(WAIT_QUEUE *)(pool_ptr->task_wait_header));
} //end if
return (oldstatus);
}
//如果定期执行碎片的回收,是否可行
/*
*********************************************************************************************************
* 释放先前分配的一个存储块到其存储池,若有任务在存储池上等待分配,则释放给等待队列上的某个任务
并执行碎快的合并
*********************************************************************************************************
*/
STATUS FreeMem(void *memory,INT32U size)
{
STATUS status;
BOOLEAN found;
MEM_MCB *pool_ptr;
struct BLOCK_STRUCT *block;
struct BLOCK_STRUCT *p,*q;
INT8U *top;
SIGNED i;
ULONG j;
if (memory== NULL ) /* Not allowed to delete idle pool */
return (ERR_INVALID_POINTER);
if (size==0 )
return (ERR_INVALID_SIZE);
#if DEBUG
DebugLog(FREE_MEM,pool_id);//在日志中记录操作,时间等信息
#endif
/**************************************************************************
寻找所在的存储池
***************************************************************************/
found=FALSE;
EnLock();
for (i=MAX_POOL_NUM-1; i>=0 ; i--){
if(MemPoolTable[i]==NULL)
continue;
if ((memory>=MemPoolTable[i]->start_address) && ((INT8U *)memory < (INT8U *)(MemPoolTable[i]->start_address)+MemPoolTable[i]->pool_size)){
found=TRUE;
break;
}
}
UnLock();
if (!found)
return (ERR_INVALID_POINTER);
pool_ptr=MemPoolTable[i];
DoProtect(pool_ptr);
status=_FreeTask(pool_ptr,&memory,&size);
if(size==0) {//释放的存储块完全释放给等待任务使用
if (status==TRUE)
_ControlToSystem();
UnProtect(pool_ptr);
return (OK);
}
if(size>0)//等待的任务未用完释放的存储块,插入链表
block = (struct BLOCK_STRUCT *)memory;
p= pool_ptr->available_header;
do{
if(p>block) break;
p=p->next;
}while (p!=pool_ptr->available_header);
q=p->prev;
if ((top=(INT8U *)q + q->block_size)>(INT8U *)block && q!=pool_ptr->available_header ||
p!=NULL && ((INT8U *)block +size) > (INT8U *)p ) {
UnProtect(pool_ptr);
return (ERR_INVALID_POINTER);
}
if(p==NULL){
block->next =block;
block->prev=block;
block->block_size = size;
pool_ptr->available_header=block;
q=block;
}
else if (top == (INT8U *)block )
q->block_size += size;
else {
block->block_size = size;
block->next = p;
p->prev=block;
q->next = block;
block->prev=q;
if(p==pool_ptr->available_header)
pool_ptr->available_header=block;
q = block;
}
if (( q->block_size + (INT8U *)q ) == (INT8U *)p) {
q->block_size += p->block_size;
q->next = p->next;
p->next->prev=q;
if(p==pool_ptr->available_header)
pool_ptr->available_header=q;
}
block =q;
j=q->block_size;
if(j!=size)
status= _FreeTask(pool_ptr,&(void *)q,&j);
if(j==0){
block->prev->next=block->next;
block->next->prev= block->prev;
if(block->next==pool_ptr->available_header)
pool_ptr->available_header=NULL;
}
else if(j<block->block_size){ //未用完合并后的存储块,重新插入链表
q->block_size=j;
block->prev->next=q;
q->prev=block->prev;
q->next=block->next;
block->next->prev=q;
if(block==pool_ptr->available_header)
pool_ptr->available_header=q;
}
else
--pool_ptr->ref_count;
UnProtect(pool_ptr);
if (status==TRUE)
_ControlToSystem();
return (OK);
}
/*
*********************************************************************************************************
* 在一个存储池上的挂起结构上的某个任务恢复或删除时,清除相应等待列表上的项
*********************************************************************************************************
*/
static void CleanupPool(void *information)
{
MEM_MCB *pool_ptr;
TASK_TCB *task_ptr;
WAIT_QUEUE *linknode;
pool_ptr=(MEM_MCB *)information;
UnProtect(pool_ptr);
EnLock();
linknode=pool_ptr->task_wait_header;
do{
task_ptr=linknode->task_ptr;
if (task_ptr==((TASK_TCB *)KERNAL.current_thread)){
pool_ptr->tasks_waiting--;
DelList(&(void *)(pool_ptr->task_wait_header),linknode);
#if WAIT_QUEUE_ALLOC_MODE
linknode->queue_ptr=WaitQueueFreeList;
WaitQueueFreeList=linknode;
#endif
}
linknode=(WAIT_QUEUE *)(linknode->next) ;
if (linknode==NULL)
break;
}while(linknode!=pool_ptr->task_wait_header);
UnLock();
}
/*
*********************************************************************************************************
* 列出系统中存在的存储池信息
*********************************************************************************************************
*/
STATUS ListMemPool(SIGNED pool_id,POOL_DATA **pool_lst)
{
struct BLOCK_STRUCT *pheader;
UNSIGNED num,i;
MEM_MCB *pool_ptr;
if (pool_id+1<0 || pool_id >=MAX_POOL_NUM) { /* Not allowed to delete idle task */
return (ERR_INVALID_POOL);
}
if(pool_id>=0){
pool_ptr=MemPoolTable[pool_id];
DoProtect(pool_ptr);
if (pool_ptr == NULL) /* Not allowed to delete idle task */
return (ERR_INVALID_POOL);
pheader=(struct BLOCK_STRUCT *)(pool_ptr->available_header);
num=0;
do {
num+=pheader->block_size;
pheader=pheader->next;
}while((pheader!= (struct BLOCK_STRUCT *)pool_ptr->available_header) && (pheader!=NULL));
(*pool_lst)->availables=num;
(*pool_lst)->suspend_type=pool_ptr->suspend_type;
(*pool_lst)->ref_count=pool_ptr->ref_count;
(*pool_lst)->tasks_waiting=pool_ptr->tasks_waiting;
(*pool_lst)->task_id=(pool_ptr->task_wait_header)->task_ptr->id;
UnProtect(pool_ptr);
return (OK);
}
else{
for(i=0;i<MAX_POOL_NUM;i++){
pool_ptr=MemPoolTable[pool_id];
DoProtect(pool_ptr);
if (pool_ptr){ /* Not allowed to delete idle task */
pheader=(struct BLOCK_STRUCT *)(pool_ptr->available_header);
num=0;
do {
num+=pheader->block_size;
pheader=pheader->next;
}while((pheader!= (struct BLOCK_STRUCT *)pool_ptr->available_header) && (pheader!=NULL));
(*pool_lst)->availables=num;
(*pool_lst)->suspend_type=pool_ptr->suspend_type;
(*pool_lst)->ref_count=pool_ptr->ref_count;
(*pool_lst)->tasks_waiting=pool_ptr->tasks_waiting;
(*pool_lst)->task_id=(pool_ptr->task_wait_header)->task_ptr->id;
(pool_lst)++;
}
UnProtect(pool_ptr);
}
return (OK);
}
}
/*
*********************************************************************************************************
* 存储池模块的初始化
创建两个系统使用的存储池
*********************************************************************************************************
*/
#define TCB_POOL_SIZE 1024
#define STACK_POOL_SIZE 4096
static MEM_MCB SysMemPool;
static MEM_MCB EventPool;
static MEM_MCB TcbPool;
static MEM_MCB StackPool;
void KernalMemInit(void *first_available_memory)
{
void *pointer;
KERNAL.mem_pool=CreateBlockMemPool(&SysMemPool,first_available_memory,SYS_POOL_SIZE);
AllocMem(KERNAL.mem_pool,&pointer,EVENT_POOL_SIZE,-1);
KERNAL.event_pool=CreateEvenMemPool(&EventPool,pointer,EVENT_POOL_SIZE,sizeof(OS_EVENT));
AllocMem(KERNAL.mem_pool,&pointer,TCB_POOL_SIZE,-1);
KERNAL.task_pool=CreateEvenMemPool(&TcbPool,pointer,TCB_POOL_SIZE,sizeof(TASK_TCB));
AllocMem(KERNAL.mem_pool,&pointer,STACK_POOL_SIZE,-1);
KERNAL.stack_pool=CreateEvenMemPool(&StackPool,pointer,STACK_POOL_SIZE,sizeof(STK_DEFAULT));
}
void MemPoolInit(void)
{
UNSIGNED i;
for(i=0;i<MAX_POOL_NUM;i++)
MemPoolTable[i]=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -