等待一个消息队列中的消息,OSQPend()
来源:互联网 发布:兄弟连培训php学费多少 编辑:程序博客网 时间:2024/05/23 15:25
程序清单 L6.22是OSQPend()函数的源代码。OSQPend()函数首先检查事件控制块是否是由OSQCreate()函数建立的[L6.22(1)],接着,该函数检查消息队列中是否有消息可用(即.OSQEntries是否大于0)[L6.22(2)]。如果有,OSQPend()函数将指向消息的指针复制到msg变量中,并让.OSQOut指针指向队列中的下一个单元[L6.22(3)],然后将队列中的有效消息数减1 [L6.22(4)]。因为消息队列是一个循环的缓冲区,OSQPend()函数需要检查.OSQOut是否超过了队列中的最后一个单元 [L6.22(5)]。当发生这种越界时,就要将.OSQOut重新调整到指向队列的起始单元 [L6.22(6)]。这是我们调用OSQPend()函数时所期望的,也是执行OSQPend()函数最快的路径。程序清单 L6.22 在一个消息队列中等待一条消息void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err){ void *msg; OS_Q *pq; OS_ENTER_CRITICAL(); if (pevent->OSEventType != OS_EVENT_TYPE_Q) { (1) OS_EXIT_CRITICAL(); *err = OS_ERR_EVENT_TYPE; return ((void *)0); } pq = pevent->OSEventPtr; if (pq->OSQEntries != 0) { (2) msg = *pq->OSQOut++; (3) pq->OSQEntries--; (4) if (pq->OSQOut == pq->OSQEnd) { (5) pq->OSQOut = pq->OSQStart; (6) } OS_EXIT_CRITICAL(); *err = OS_NO_ERR; } else if (OSIntNesting > 0) { (7) OS_EXIT_CRITICAL(); *err = OS_ERR_PEND_ISR; } else { OSTCBCur->OSTCBStat |= OS_STAT_Q; (8) OSTCBCur->OSTCBDly = timeout; OSEventTaskWait(pevent); OS_EXIT_CRITICAL(); OSSched(); (9) OS_ENTER_CRITICAL(); if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) { (10) OSTCBCur->OSTCBMsg = (void *)0; OSTCBCur->OSTCBStat = OS_STAT_RDY; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; (11) OS_EXIT_CRITICAL(); *err = OS_NO_ERR; } else if (OSTCBCur->OSTCBStat & OS_STAT_Q) { (12) OSEventTO(pevent); (13) OS_EXIT_CRITICAL(); msg = (void *)0; (14) *err = OS_TIMEOUT; } else { msg = *pq->OSQOut++; (15) pq->OSQEntries--; if (pq->OSQOut == pq->OSQEnd) { pq->OSQOut = pq->OSQStart; } OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; (16) OS_EXIT_CRITICAL(); *err = OS_NO_ERR; } } return (msg); (17)}如果这时消息队列中没有消息(.OSEventEntries是0),OSQPend()函数检查它的调用者是否是中断服务子程序[L6.22(7)]。象OSSemPend()和OSMboxPend()函数一样,不能在中断服务子程序中调用OSQPend(),因为中断服务子程序是不能等待的。但是,如果消息队列中有消息,即使从中断服务子程序中调用OSQPend()函数,也一样是成功的。如果消息队列中没有消息,调用OSQPend()函数的任务被挂起[L6.22(8)]。当有其它的任务向该消息队列发送了消息或者等待时间超时,并且该任务成为最高优先级任务时,OSSched()返回[L6.22(9)]。这时,OSQPend()要检查是否有消息被放到该任务的任务控制块中[L6.22(10)]。如果有,那么该次函数调用成功,把任务的任务控制块中指向消息队列的指针删除[L6.22(17)],并将对应的消息被返回到调用函数[L6.22(17)]。在OSQPend()函数中,通过检查任务的任务控制块中的.OSTCBStat域,可以知道是否等到时间超时。如果其对应的OS_STAT_Q位被置1,说明任务等待已经超时[L6.22(12)]。这时,通过调用函数OSEventTo()可以将任务从消息队列的等待任务列表中删除[L6.22(13)]。这时,因为消息队列中没有消息,所以返回的指针是NULL[L6.22(14)]。如果任务控制块标志位中的OS_STAT_Q位没有被置1,说明有任务发出了一条消息。OSQPend()函数从队列中取出该消息[L6.22(15)]。然后,将任务的任务控制中指向事件控制块的指针删除[L6.22(16)]。
0 0
- 等待一个消息队列中的消息,OSQPend()
- 等待一个邮箱中的消息,OSMboxPend()
- 无等待地从一个消息队列中取得消息, OSQAccept()
- 无等待地从一个消息队列中取得消息, OSQAccept()
- miniGUI中的消息队列
- miniGUI中的消息队列
- java中的消息队列
- java中的消息队列
- Linux中的消息队列
- FAQ12:每个线程一个消息队列?还是线程中的每个窗口各有一个消息队列?
- 处理消息队列中的所有消息
- 建立一个消息队列,OSQCreate()
- 一个Redis消息队列实现
- 树言树语:等待呼喊中的面试消息
- 【openstack】openstack中的消息队列
- 理解osIII中的消息队列
- 等待消息队列为空(Demo) wait+notify
- 消息与消息队列
- AO二次开发环境搭建
- HTML中常用的js技巧和方法
- nginx启用ssl模块以支持https
- 禁用idea的QL检查
- Jsp标签
- 等待一个消息队列中的消息,OSQPend()
- 开源 java CMS
- android_阿里WEEX js文件与原生代码数据交互
- 51nod 1085 背包问题
- 返回引用的两数相加
- 通配符选择器(理解)
- zookeeper入门系列-理论基础-zab协议
- 每天一个Linux命令(28): 详解/etc/group文件
- 不受视图切换影响的小小的提示框