⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queue.c

📁 一种操作系统源码核
💻 C
📖 第 1 页 / 共 2 页
字号:
    	if (queue_ptr == NULL)                                  /* Not allowed to Del idle Queue     */
        	return (ERR_INVALID_QUEUE);
    	if(queue_ptr->available==NULL && queue_ptr->task_wait_header){//有任务等待接收消息,恢复任务,消息放入队列队列中的任务的挂起结构的消息域
        	queue_ptr->task_wait_header->queue_message=message;
        	task_ptr=(queue_ptr->task_wait_header)->task_ptr;
   		UnProtect(queue_ptr);
   		status=_ResumeTask(task_ptr,EVENT_SUSPEND);
        	if (status==TRUE)
            		_ControlToSystem();
		return (OK);
    	}
	ret=_AddWaitQueue(queue_ptr,suspend);
    	if(ret==OK){
    		DoProtect(queue_ptr);
           	queue_ptr->available++;
            	if(queue_ptr->read_pointer==queue_ptr->queue_start)
               		queue_ptr->read_pointer=queue_ptr->queue_end;
            	else 
               		(queue_ptr->read_pointer)--;
            	*(queue_ptr->read_pointer)=message;
            	UnProtect(queue_ptr);   
     	}        
     	return ret;

    
}
/*
*********************************************************************************************************
        广播一条消息到队列,当前在队列上等待接收消息的任务都接收到该消息并恢复
*********************************************************************************************************
*/
STATUS BroadToQueue(SIGNED queue_id, void *message,SIGNED suspend)
{
   	WAIT_QUEUE *linknode;
   	TASK_TCB *task_ptr;
   
	STATUS status,oldstate,ret;
    	QUEUE_QCB *queue_ptr;
    	
    	if (message == NULL) {                                 /* Not allowed to Del idle Queue     */
        	return (ERR_INVALID_POINTER);
    	}
    	if (queue_id<0 || queue_id >=MAX_QUEUE_NUM) {                                 /* Not allowed to Del idle task     */
        	return (ERR_INVALID_QUEUE);
    	}
    	queue_ptr=QueueTable[queue_id];
    	#if DEBUG
        	DebugLog(BROADTO_QUEUE,queue_id);//在日志中记录操作,时间等信息
    	#endif
    	DoProtect(queue_ptr);   
    	if (queue_ptr == NULL)                                  /* Not allowed to Del idle Queue     */
        	return (ERR_INVALID_QUEUE);
    	if (queue_ptr->available==NULL && queue_ptr->task_wait_header){//有任务在等待接收,消息并且放入队列中的消息域,恢复任务,
        	//  Queue_ptr->message_present=TRUE;
        	linknode=queue_ptr->task_wait_header;
        	do{
          		task_ptr=linknode->task_ptr;
	   		linknode->queue_message=message;
	   		status=_ResumeTask(task_ptr,EVENT_SUSPEND);
           		if (status==TRUE)
               			oldstate =status;
           		linknode=(WAIT_QUEUE *)(linknode->next);
        	}while(linknode!=queue_ptr->task_wait_header);
        	UnProtect(queue_ptr);
        	if(oldstate==TRUE)
           		_ControlToSystem();
        	return (OK);
    	}
	ret=_AddWaitQueue(queue_ptr,suspend);
    	if(ret==OK){
    		DoProtect(queue_ptr);
          	queue_ptr->available++;
          	*(queue_ptr->write_pointer)=message;
          	if(queue_ptr->write_pointer==queue_ptr->queue_end)
             		queue_ptr->write_pointer=queue_ptr->queue_start;
          	else 
             		(queue_ptr->write_pointer)++;
          	UnProtect(queue_ptr);   
     	}        
     	return ret;
}
/*
*********************************************************************************************************
*                                    RECEIVE A MESSAGE FROM A Queue

*********************************************************************************************************
*/
void * RecvFromQueue(SIGNED queue_id,INT8 *err,SIGNED suspend)
{
  	WAIT_QUEUE *task_suspend;
  	TASK_TCB *task_ptr;
  	void *message;
  	STATUS status;
  	QUEUE_QCB *queue_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 (queue_id<0 || queue_id >=MAX_QUEUE_NUM) {                                 /* Not allowed to Del idle task     */
     		*err=ERR_INVALID_QUEUE;
      		return ((void *)0);
  	}
  	queue_ptr=QueueTable[queue_id];
  	#if DEBUG
      		DebugLog(RECV_FROM_QUEUE,queue_id);//在日志中记录操作,时间等信息
  	#endif
  	DoProtect(queue_ptr);
  	if (queue_ptr == NULL) {                                 /* Not allowed to Del idle Queue     */
     		*err=ERR_INVALID_QUEUE;
     		return ((void *)0);
   	}
  	if(queue_ptr->available==0){   //队列空
     		if(suspend!=NO_SUSPEND){//任务挂起
        		if (((TASK_TCB *)KERNAL.current_thread)->type!=TASK){
	    			UnProtect(queue_ptr);
	    			*err=ERR_INVALID_SUSPEND;
	    			return ((void *)0);
	 		}
        		queue_ptr->tasks_waiting++;
			task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
			task_suspend->priority=GetPriority(((TASK_TCB *)KERNAL.current_thread)->id);
        		AddList(&(void *)(queue_ptr->task_wait_header),task_suspend,queue_ptr->suspend_type);
        		UnProtect(queue_ptr);
			_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupQueue,queue_ptr,suspend);
			_ControlToSystem();
			Enlock(); 
           		#if WAIT_QUEUE_ALLOC_MODE
 				task_suspend->queue_ptr=WaitQueueFreeList;
 				WaitQueueFreeList=task_suspend;
 			#endif
			if(queue_ptr==NULL) {
				Unlock(); 
     	   			*err=ERR_QUEUE_DELETED;
	   			return ((void *)0);
			}
        		if((queue_ptr->task_wait_header)==NULL) {
	   			Unlock(); 
	   			*err=ERR_QUEUE_RESET;
	   			return ((void *)0);
			}
			if (task_suspend->queue_message==NULL) {
	   			Unlock(); 
	   			*err=ERR_TIMEOUT;
	   			return ((void *)0);
			}
			//接收到消息,移去挂起结构
        		queue_ptr->tasks_waiting--; 
			message=task_suspend->queue_message;
			DelList(&(void *)(queue_ptr->task_wait_header),task_suspend);
			Unlock(); 
        		*err=OK;
        		
        		return (message);
     		}
     		else{
        		UnProtect(queue_ptr);
			*err=ERR_QUEUE_EMPTY;
			return ((void *)0);
     		}
  	}
 	else{ ////队列中有消息,取得消息
     		message=*(queue_ptr->read_pointer);
     		if(queue_ptr->read_pointer==queue_ptr->queue_end)
        		queue_ptr->read_pointer=queue_ptr->queue_start;
     		else  
        		(queue_ptr->read_pointer)++;
     		queue_ptr->available--;
     		if(queue_ptr->task_wait_header){  //这时的等待的任务肯定是要发送的任务,判断空间是否足够若够则恢复该任务
        		task_ptr=(queue_ptr->task_wait_header)->task_ptr;
        		UnProtect(queue_ptr);
        		status=_ResumeTask(task_ptr,EVENT_SUSPEND);
        		if (status==TRUE)
           			_ControlToSystem();
			*err=OK;
        		return (message);
     		}
     		UnProtect(queue_ptr);
     		*err=OK;
     		return (message);
  	}

}
/*
*********************************************************************************************************
*                                    在一个队列上的等待列表上的某个任务恢复或删除时,清除相应等待列表上的项

*********************************************************************************************************
*/
static void CleanupQueue(void *information)
{
    	QUEUE_QCB *queue_ptr;
    	TASK_TCB *task_ptr;
    	WAIT_QUEUE *linknode;
    	queue_ptr=(QUEUE_QCB *)information;
    	UnProtect(queue_ptr);
    	EnLock();
    	linknode=queue_ptr->task_wait_header;
    	do{
		task_ptr=linknode->task_ptr;
        	if (task_ptr==((TASK_TCB*)KERNAL.current_thread)){
	   		queue_ptr->tasks_waiting--; 
	   		DelList(&(void *)(queue_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!=queue_ptr->task_wait_header);
    	UnLock();
}
/*
*********************************************************************************************************
*                              列出系统中存在的队列信息

*********************************************************************************************************
*/
STATUS ListQueue(SIGNED queue_id,QUEUE_DATA **queue_lst)
{
   	QUEUE_QCB *queue_ptr;
   	UNSIGNED i;
   	if (queue_id+1<0 || queue_id >=MAX_QUEUE_NUM) {                                 /* Not allowed to Del idle task     */
       		return (ERR_INVALID_QUEUE);
   	}
   	if(queue_id>=0){
   		queue_ptr=QueueTable[queue_id];
   		DoProtect(queue_ptr);
   		if (queue_ptr == NULL)                                  /* Not allowed to Del idle task     */
			return (ERR_INVALID_QUEUE);
		(*queue_lst)->suspend_type=queue_ptr->suspend_type;
		(*queue_lst)->tasks_waiting=queue_ptr->tasks_waiting;
		(*queue_lst)->available=queue_ptr->available;
		(*queue_lst)->task_id=(queue_ptr->task_wait_header)->task_ptr->id;
		UnProtect(queue_ptr);
		return (OK);
	}
	else{
		for(i=0;i<MAX_QUEUE_NUM;i++){
			queue_ptr=QueueTable[i];
			DoProtect(queue_ptr);
			if (queue_ptr){                                  /* Not allowed to Del idle task     */
				(*queue_lst)->tasks_waiting=queue_ptr->tasks_waiting;
				(*queue_lst)->available=queue_ptr->available;
				(*queue_lst)->suspend_type=queue_ptr->suspend_type;
				(*queue_lst)->task_id=(queue_ptr->task_wait_header)->task_ptr->id;
				queue_lst++;
			}
			UnProtect(queue_ptr);
		}
		return (OK);
	}
}		

/*
*********************************************************************************************************
*                           队列模块的初始化

*********************************************************************************************************
*/
void QueueInit(void)
{
   	UNSIGNED i;
   	for(i=0;i<MAX_QUEUE_NUM;i++)
    		QueueTable[i]=NULL;
}
 /*
*********************************************************************************************************
*                             This function resets a Queue back to the initial state.

*********************************************************************************************************
*/
STATUS ResetQueue(SIGNED queue_id)
{
   	WAIT_QUEUE *linknode;
   	STATUS oldstate,state;
   	QUEUE_QCB *queue_ptr;
   	if (queue_id<0 || queue_id >=MAX_QUEUE_NUM) {                                 /* Not allowed to Del idle task     */
      		return (ERR_INVALID_QUEUE);
   	}
   	queue_ptr=QueueTable[queue_id];
   	#if DEBUG
      		DebugLog(RESET_QUEUE,queue_id);//在日志中记录操作,时间等信息
   	#endif
   	oldstate=0;
   	DoProtect(queue_ptr);
   	if (queue_ptr == NULL)                                 /* Not allowed to Del idle task     */
      		return (ERR_INVALID_QUEUE);
   	// Queue_ptr->message_present=FALSE;
   	queue_ptr->read_pointer=queue_ptr->queue_start;
   	queue_ptr->write_pointer=queue_ptr->queue_start;
   	while(queue_ptr->task_wait_header){
      		state=_ResumeTask(queue_ptr->task_wait_header->task_ptr,EVENT_SUSPEND);
      		if(state==TRUE)
          		oldstate =state;
      		DelHead(&(void *)(queue_ptr->task_wait_header));
   	}
  	UnProtect(queue_ptr);
   	if(oldstate==TRUE)
       		_ControlToSystem();
   	return (OK);
}
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -