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

📄 queue.c

📁 一种操作系统源码核
💻 C
📖 第 1 页 / 共 2 页
字号:
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
/*
*********************************************************************************************************
*                                          Queue module implement  FILE
*********************************************************************************************************
*/


static QUEUE_QCB *QueueTable[MAX_QUEUE_NUM];//队列向量表
static void CleanupQueue(void *information);//队列清除函数
static QUEUE_QCB * QueueFreeList; //可用队列列表

/*
*********************************************************************************************************
*              获得一个可用的ID号                       

*********************************************************************************************************
*/
static SIGNED _NewQueueId()
{
	static UNSIGNED Next_ID;
	UNSIGNED  id;			/* process id to return		*/
        EnLock();
	if ( (id=Next_ID++) <MAX_QUEUE_NUM){
	   	if (QueueTable[id] == NULL){
	        	UnLock();
			return(id);
	   }
	}
	else if(QueueFreeList){
	    	id=QueueFreeList->id;
	   	#if ENABLE_MEM
			FreeBuff(QueueFreeList);
	    	#endif
	    	QueueFreeList=QueueFreeList->next;
	    	UnLock();
	    	return(id);
	}
	UnLock();
	return(ERR_QUEUE_FULL);

}
/*
*********************************************************************************************************
*                                   创建一个队列

*********************************************************************************************************
*/
#if ENABLE_MEM
SIGNED CreateQueue (UNSIGNED queue_size)
#else
SIGNED CreateQueue (QUEUE_QCB *queue_ptr,void **queue_start, UNSIGNED queue_size)
#endif
{
    	SIGNED queue_id,err;
    	#if ENABLE_MEM
		void *queue_start;
		QUEUE_QCB *queue_ptr;
    	#endif
    	if (queue_start==NULL ) return (ERR_INVALID_MEMORY);
    	if (queue_size==0 ) return (ERR_INVALID_SIZE);
    	queue_id=_NewQueueId();
    	if(queue_id<0)
        	return(queue_id);
    	#if ENABLE_MEM          
        	err=AllocBuff(KERNAL.event_pool,&(void *)queue_ptr,-1);
		if(err!=OK)
	    		return (ERR_NO_MEMORY);
		err=AllocMem(KERNAL.mem_pool,&queue_start,queue_size*sizeof(void *),-1);
		if(err!=OK)
	    		return (ERR_NO_MEMORY);    
    	#else
        	if (queue_ptr==NULL)  return(ERR_INVALID_QUEUE);
        	else  if(QueueTable[queue_ptr->id]==queue_ptr) return (queue_ptr->id);
    	#endif
    	#if DEBUG
        	DebugLog(CREATE_QUEUE,queue_ptr->id);//在日志中记录操作,时间等信息
    	#endif
    	QueueTable[queue_id]=queue_ptr;
    	queue_ptr->id=queue_id;
    	queue_ptr->current_protect=NULL;
    	queue_ptr->suspend_type=FIFO;	
    	queue_ptr->queue_size=queue_size;
    	queue_ptr->available=0;
    	queue_ptr->queue_start=queue_start;
    	queue_ptr->queue_end=(void *)((INT8 *)queue_start+queue_size*sizeof(void *));
    	queue_ptr->read_pointer=queue_start;
    	queue_ptr->write_pointer=queue_start;
    	queue_ptr->task_wait_header=NULL;
    	return(queue_id);

}
/*
*********************************************************************************************************
*                                      Del A Queue

*********************************************************************************************************
*/
STATUS DelQueue(SIGNED queue_id)
{
   	STATUS state,oldstate;
   	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(DELETE_QUEUE,queue_id);//在日志中记录操作,时间等信息
   	#endif
   	DoProtect(queue_ptr);
   	if (queue_ptr == NULL)                                 /* Not allowed to Del idle QUEUE     */
      		return (ERR_INVALID_QUEUE);
   	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));
   	}
   	#if ENABLE_MEM
      		FreeBuff(queue_ptr);
      		FreeMem(queue_ptr->queue_start,(queue_ptr->queue_size)*sizeof(void *));
   	#endif
   	UnProtect(queue_ptr);
   	EnLock();
	queue_ptr->next=QueueFreeList;
   	QueueFreeList=queue_ptr;
   	QueueTable[queue_id]=NULL;
   	UnLock();
   	if(oldstate==TRUE) 
      		_ControlToSystem();
   	return (OK);

}
/*
*********************************************************************************************************
*                                      队列参数设置函数

*********************************************************************************************************
*/
STATUS SysQueueCtl(SIGNED queue_id,INT8U cmd,INT8U param)
{
	STATUS ret;
	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(SYS_QUEUE_CTL,queue_id);//在日志中记录操作,时间等信息
        #endif
        DoProtect(queue_ptr);
	if (queue_ptr == NULL) {
	   	return (ERR_INVALID_QUEUE); /* Not allowed is idle task     */
	 }
	switch(cmd){
	   	case SUSPEND_TYPE:
  	      		queue_ptr->suspend_type=param;
	      		ret=OK;
	      		break;
	   	case QUEUE_SIZE:
	      		#if ENABLE_MEM
	      			ret=DelQueue(queue_id);
	      			if(ret!=OK)
	        			 break;
	      			ret=CreateQueue(param);
	     		#endif
	      		break;
          	default:
	      		ret=ERR_INVALID_CMD;
	      		break;
	}
	UnProtect(queue_ptr);
	return(ret);
}
/*
*********************************************************************************************************
*                                     SEND A MESSAGE TO A Queue

*********************************************************************************************************
*/
INT8 _AddWaitQueue(QUEUE_QCB *queue_ptr,SIGNED suspend)
{
    	WAIT_QUEUE *task_suspend;
    	#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_ptr->available>=queue_ptr->queue_size){   //队列满
        	if(suspend!=NO_SUSPEND){//任务挂起
           		if(((TASK_TCB *)KERNAL.current_thread)->type!=TASK){
               			UnProtect(queue_ptr);
               			return(ERR_INVALID_SUSPEND);
           		}
           		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();
              			return(ERR_QUEUE_DELETED);
           		}
           		if (queue_ptr->available>=queue_ptr->queue_size){
              			Unlock();
              			return(ERR_TIMEOUT);
           		}
           		if(queue_ptr->task_wait_header==NULL){
              			Unlock();
              			return(ERR_QUEUE_RESET);
           		}
           		//队列消息被另一个任务接收导致队列为空,该任务放消息到队列
           
           		queue_ptr->tasks_waiting--;  
           		DelList(&(void *)(queue_ptr->task_wait_header),task_suspend);
           		Unlock();
           		return (OK);
          
        	}
        	else{
          	 	UnProtect(queue_ptr);
           		return (ERR_QUEUE_FULL);
        	}
     	}
     	else{//队列不满,消息放入队列
              	UnProtect(queue_ptr);
		return (OK);
     	}
 }    	
	
STATUS SendToQueue(SIGNED queue_id, void *message, SIGNED suspend)
{
  
  	TASK_TCB *task_ptr;
	STATUS status,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(SENDTO_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->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++;
          	*(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;
   

}
/*
*********************************************************************************************************
*                                     SEND A MESSAGE TO Front Of A Queue

*********************************************************************************************************
*/
STATUS SendToFrontOfQueue(SIGNED queue_id, void *message, SIGNED suspend)
{
    	
    	TASK_TCB *task_ptr;
	STATUS status,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(SENDTO_FRONTOFQUEUE,queue_id);//在日志中记录操作,时间等信息
    	#endif
    	DoProtect(queue_ptr);

⌨️ 快捷键说明

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