建立一個訊息佇列,OSQCreate()
阿新 • • 發佈:2019-01-22
程式清單 L6.21是OSQCreate()函式的原始碼。該函式需要一個指標陣列來容納指向各個訊息的指標。該指標陣列必須聲名為void型別。 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)]。 另外,訊息佇列一旦建立就不能再刪除了。試想,如果有任務正在等待某個訊息佇列中的訊息,而此時又刪除該訊息佇列,將是很危險的。 程式清單 L6.21 建立一個訊息佇列 OS_EVENT *OSQCreate (void **start, INT16U size) { OS_EVENT *pevent; OS_Q *pq; OS_ENTER_CRITICAL(); pevent = OSEventFreeList; (1) if (OSEventFreeList != (OS_EVENT *)0) { OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; (2) } OS_EXIT_CRITICAL(); if (pevent != (OS_EVENT *)0) { OS_ENTER_CRITICAL(); pq = OSQFreeList; (3) if (OSQFreeList != (OS_Q *)0) { OSQFreeList = OSQFreeList->OSQPtr; } OS_EXIT_CRITICAL(); if (pq != (OS_Q *)0) { pq->OSQStart = start; (4) pq->OSQEnd = &start[size]; pq->OSQIn = start; pq->OSQOut = start; pq->OSQSize = size; pq->OSQEntries = 0; pevent->OSEventType = OS_EVENT_TYPE_Q; (5) pevent->OSEventPtr = pq; (6) OSEventWaitListInit(pevent); (7) } else { OS_ENTER_CRITICAL(); pevent->OSEventPtr = (void *)OSEventFreeList; (8) OSEventFreeList = pevent; OS_EXIT_CRITICAL(); pevent = (OS_EVENT *)0; } } return (pevent); (9) }