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 + -
显示快捷键?