0412

来源:互联网 发布:淘宝费列罗真假 编辑:程序博客网 时间:2024/06/04 18:30

建立一个消息队列,OSQCreate()

  1. 程序清单 L6.21是OSQCreate()函数的源代码。该函数需要一个指针数组来容纳指向各个消息的指针。该指针数组必须声名为void类型。  
  2. OSQCreate()首先从空闲事件控制块链表中取得一个事件控制块(见图F6.3)[L6.21(1)],并对剩下的空闲事件控制块列表的指针做相应的调整,使它指向下一个空闲事件控制块[L6.21(2)]。接着,OSQCreate()函数从空闲队列控制块列表中取出一个队列控制块[L6.21(3)]。如果有空闲队列控制块是可以的,就对其进行初始化[L6.21(4)]。然后该函数将事件控制块的类型设置为OS_EVENT_TYPE_Q [L6.21(5)],并使其.OSEventPtr指针指向队列控制块[L6.21(6)]。OSQCreate()还要调用OSEventWaitListInit()函数对事件控制块的等待任务列表初始化[见6.01节,初始化一个事件控制块,OSEventWaitListInit()] [L6.21(7)]。因为此时消息队列正在初始化,显然它的等待任务列表是空的。最后,OSQCreate()向它的调用函数返回一个指向事件控制块的指针[L6.21(9)]。该指针将在调用OSQPend(),OSQPost(),OSQPostFront(),OSQFlush(),OSQAccept()和OSQQuery()等消息队列处理函数时使用。因此,该指针可以被看作是对应消息队列的句柄。值得注意的是,如果此时没有空闲的事件控制块,OSQCreate()函数将返回一个NULL指针。如果没有队列控制块可以使用,为了不浪费事件控制块资源,OSQCreate()函数将把刚刚取得的事件控制块重新返还给空闲事件控制块列表 [L6.21(8)]。  
  3. 另外,消息队列一旦建立就不能再删除了。试想,如果有任务正在等待某个消息队列中的消息,而此时又删除该消息队列,将是很危险的。  
  4.   
  5. 程序清单 L6.21 建立一个消息队列  
  6. OS_EVENT *OSQCreate (void **start, INT16U size)  
  7. {  
  8.     OS_EVENT *pevent;  
  9.     OS_Q     *pq;  
  10.   
  11.   
  12.     OS_ENTER_CRITICAL();  
  13.     pevent = OSEventFreeList;                                           (1)  
  14.     if (OSEventFreeList != (OS_EVENT *)0) {  
  15.         OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;      (2)  
  16.     }  
  17.     OS_EXIT_CRITICAL();  
  18.     if (pevent != (OS_EVENT *)0) {  
  19.         OS_ENTER_CRITICAL();  
  20.         pq = OSQFreeList;                                               (3)  
  21.         if (OSQFreeList != (OS_Q *)0) {  
  22.             OSQFreeList = OSQFreeList->OSQPtr;  
  23.         }  
  24.         OS_EXIT_CRITICAL();  
  25.         if (pq != (OS_Q *)0) {  
  26.             pq->OSQStart        = start;                              (4)  
  27.             pq->OSQEnd          = &start[size];  
  28.             pq->OSQIn           = start;  
  29.             pq->OSQOut          = start;  
  30.             pq->OSQSize         = size;  
  31.             pq->OSQEntries      = 0;  
  32.             pevent->OSEventType = OS_EVENT_TYPE_Q;                      (5)  
  33.             pevent->OSEventPtr  = pq;                                    (6)  
  34.             OSEventWaitListInit(pevent);                                 (7)  
  35.         } else {  
  36.             OS_ENTER_CRITICAL();  
  37.             pevent->OSEventPtr = (void *)OSEventFreeList;                (8)            OSEventFreeList    = pevent;  
  38.             OS_EXIT_CRITICAL();  
  39.             pevent = (OS_EVENT *)0;  
  40.         }  
  41.     }  
  42.     return (pevent);                                                     (9)  
  43. }  

0 0
原创粉丝点击