mailbox.c
来自「一种操作系统源码核」· C语言 代码 · 共 549 行 · 第 1/2 页
C
549 行
INT8 state,oldstate;
MAILBOX_MCB *mailbox_ptr;
INT8 ret=OK;
if (message == NULL) /* Not allowed to Del idle mailbox */
return (ERR_INVALID_POINTER);
if (mailbox_id<0 || mailbox_id >=MAX_MAILBOX_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_MAILBOX);
}
mailbox_ptr=MailboxTable[mailbox_id];
#if DEBUG
DebugLog(BROADTO_MAILBOX,mailbox_id);//在日志中记录操作,时间等信息
#endif
DoProtect(mailbox_ptr);
if (mailbox_ptr == NULL) /* Not allowed to Del idle mailbox */
return (ERR_INVALID_MAILBOX);
if (mailbox_ptr->message_area==NULL){ //邮箱空
if (mailbox_ptr->task_wait_header){//邮箱空有任务等待,恢复任务,消息并且放入邮箱中的消息域
linknode=mailbox_ptr->task_wait_header;
do{
linknode->mail_message=message;
state=_ResumeTask(linknode->task_ptr,EVENT_SUSPEND);
if(state==TRUE)
oldstate =state;
linknode=(WAIT_QUEUE *)(linknode->next);
}while(linknode!=mailbox_ptr->task_wait_header);
UnProtect(mailbox_ptr);
if(oldstate==TRUE)
_ControlToSystem();
}
else{//无任务在等待,消息放入邮箱,置消息存在标志
mailbox_ptr->message_area=message;
UnProtect(mailbox_ptr);
}
}
else { //邮箱满
ret=_AddWaitQueue(mailbox_ptr,suspend);
if(ret==OK)
mailbox_ptr->message_area=message;
}
return (ret);
}
/*
*********************************************************************************************************
* RECEIVE A MESSAGE FROM A MAILBOX
*********************************************************************************************************
*/
void *RecvFromMailbox(SIGNED mailbox_id,INT8 *err, SIGNED suspend)
{
void *message;
WAIT_QUEUE *task_suspend;
TASK_TCB *task_ptr;
STATUS status;
MAILBOX_MCB *mailbox_ptr;
#if WAIT_QUEUE_ALLOC_MODE
task_suspend=WaitQueueFreeList;
WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
#else
WAIT_QUEUE queue_wait_queue;
task_suspend=&queue_wait_queue;
#endif
if (message == NULL) { /* Not allowed to Del idle mailbox */
*err=ERR_INVALID_POINTER;
return ((void *)0);
}
if (mailbox_id<0 || mailbox_id >=MAX_MAILBOX_NUM) {
*err=ERR_INVALID_MAILBOX; /* Not allowed to Del idle task */
return ((void *)0);
}
mailbox_ptr=MailboxTable[mailbox_id];
#if DEBUG
DebugLog(RECVFROM_MAILBOX,mailbox_id);//在日志中记录操作,时间等信息
#endif
DoProtect(mailbox_ptr);
if (mailbox_ptr == NULL) { /* Not allowed to Del idle mailbox */
*err=ERR_INVALID_MAILBOX;
return ((void *)0);
}
if(mailbox_ptr->message_area==NULL){ //邮箱空
if(suspend!=NO_SUSPEND){//任务挂起
if (((TASK_TCB *)KERNAL.current_thread)->type!=TASK){
UnProtect(mailbox_ptr);
*err=ERR_INVALID_SUSPEND;
return ((void *)0);
}
mailbox_ptr->tasks_waiting++;
task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
task_suspend->priority=GetPriority(((TASK_TCB *)KERNAL.current_thread)->id);
AddList(&(void *)(mailbox_ptr->task_wait_header),task_suspend,mailbox_ptr->suspend_type);
UnProtect(mailbox_ptr);
_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupMailbox,mailbox_ptr,suspend);
_ControlToSystem();
Enlock();
#if WAIT_QUEUE_ALLOC_MODE
task_suspend->queue_ptr=WaitQueueFreeList;
WaitQueueFreeList=task_suspend;
#endif
if(mailbox_ptr==NULL) {
Unlock();
*err=ERR_MAILBOX_DELETED;
return ((void *)0);
}
if(mailbox_ptr->task_wait_header==NULL){
Unlock();
*err=ERR_MAILBOX_RESET;
return ((void *)0);
}
if (mailbox_ptr->task_wait_header->mail_message==NULL){
Unlock();
*err=ERR_TIMEOUT;
return ((void *)0);
}
else{ //接收到消息,移去挂起结构
message= mailbox_ptr->task_wait_header->mail_message;
mailbox_ptr->tasks_waiting--;
DelList(&(void *)(mailbox_ptr->task_wait_header),task_suspend);
Unlock();
*err=OK;
return (message);
}
}
else{
UnProtect(mailbox_ptr);
*err=ERR_MAILBOX_EMPTY;
return ((void *)0);
}
}
else{ ////邮箱中有消息,取得消息并清消息存在标志
message=mailbox_ptr->message_area;
mailbox_ptr->message_area=NULL;
if(mailbox_ptr->task_wait_header){ //若有任务等待发送,则恢复任务
task_ptr=(mailbox_ptr->task_wait_header)->task_ptr;
UnProtect(mailbox_ptr);
status=_ResumeTask(task_ptr,EVENT_SUSPEND);
if (status==TRUE)
_ControlToSystem();
}
UnProtect(mailbox_ptr);
*err=OK;
}
return (message);
}
/*
*********************************************************************************************************
* 在一个邮箱上的挂起结构上的某个任务恢复或删除时,清除相应等待列表上的项
*********************************************************************************************************
*/
static void CleanupMailbox(void *information)
{
MAILBOX_MCB *mailbox_ptr;
TASK_TCB *task_ptr;
WAIT_QUEUE *linknode;
mailbox_ptr=(MAILBOX_MCB *)information;
UnProtect(mailbox_ptr);
EnLock();
linknode=mailbox_ptr->task_wait_header;
do{
task_ptr=linknode->task_ptr;
if (task_ptr==(((TASK_TCB *)KERNAL.current_thread))){
mailbox_ptr->tasks_waiting--;
DelList(&(void *)(mailbox_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!=mailbox_ptr->task_wait_header);
UnLock();
}
/*
*********************************************************************************************************
* 列出系统中存在的邮箱信息
*********************************************************************************************************
*/
STATUS ListMailbox(SIGNED mailbox_id,MAILBOX_DATA **mailbox_lst)
{
MAILBOX_MCB *mailbox_ptr;
UNSIGNED i;
if (mailbox_id+1<0 || mailbox_id >=MAX_MAILBOX_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_MAILBOX);
}
if(mailbox_id>=0){
mailbox_ptr=MailboxTable[mailbox_id];
DoProtect(mailbox_ptr);
if (mailbox_ptr == NULL) /* Not allowed to Del idle task */
return (ERR_INVALID_MAILBOX);
(*mailbox_lst)->tasks_waiting=mailbox_ptr->tasks_waiting;
(*mailbox_lst)->task_id=(mailbox_ptr->task_wait_header)->task_ptr->id;
(*mailbox_lst)->suspend_type=mailbox_ptr->suspend_type;
UnProtect(mailbox_ptr);
return (OK);
}
else{
for(i=0;i<MAX_MAILBOX_NUM;i++){
mailbox_ptr=MailboxTable[i];
DoProtect(mailbox_ptr);
if (mailbox_ptr){
(*mailbox_lst)->tasks_waiting=mailbox_ptr->tasks_waiting;
(*mailbox_lst)->task_id=(mailbox_ptr->task_wait_header)->task_ptr->id;
(*mailbox_lst)->suspend_type=mailbox_ptr->suspend_type;
mailbox_lst++;
}
UnProtect(mailbox_ptr);
}
return (OK);
}
}
/*
*********************************************************************************************************
* 邮箱 模块的初始化
*********************************************************************************************************
*/
void MailboxInit(void)
{
UNSIGNED i;
for(i=0;i<MAX_MAILBOX_NUM;i++)
MailboxTable[i]=NULL;
}
/*
*********************************************************************************************************
* This function resets a mailbox back to the initial state.
*********************************************************************************************************
*/
INT8 ResetMailbox(SIGNED mailbox_id)
{
WAIT_QUEUE *linknode;
INT8 oldstate,state;
MAILBOX_MCB *mailbox_ptr;
if (mailbox_id<0 || mailbox_id >=MAX_MAILBOX_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_MAILBOX);
}
mailbox_ptr=MailboxTable[mailbox_id];
#if DEBUG
DebugLog(RESET_MAILBOX,mailbox_id);//在日志中记录操作,时间等信息
#endif
oldstate=0;
DoProtect(mailbox_ptr);
if (mailbox_ptr == NULL) /* Not allowed to Del idle task */
return (ERR_INVALID_MAILBOX);
while(mailbox_ptr->task_wait_header){
state=_ResumeTask(mailbox_ptr->task_wait_header->task_ptr,EVENT_SUSPEND);
if(state==TRUE)
oldstate =state;
DelHead(&(void *)(mailbox_ptr->task_wait_header));
}
UnProtect(mailbox_ptr);
if(oldstate==TRUE)
_ControlToSystem();
return (OK);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?