Chapter 6 Event Control Block ECB 1 Synchronization
Chapter 6: Event Control Block (ECB) 1
Synchronization & Communication Synchronization • Semaphore (counting semaphore) • Mutual Exclusion Semaphore (binary semaphore + PCP) • Event Flag Communication • Message Mailbox • Message Queue 2
General operations • OSXxx. Create • OSXxx. Del • OSXxx. Pend Wait for Xxx • OSXxx. Accept A non-blocking version of OSXxx. Pend • OSXxx. Post Release Xxx • OSXxx. Query 3
Blocking System call Task. A Task. B “Device Not Ready” 4
Nonblocking System call Task. A return -1 “Device Not Ready” 5
Asynchronous System call Task. A “Device Not Ready” return 0 6
Semantics of ECB • ECB (Event Control Block) • An ISR or a task can signal an ECB • Only a task can wait for an ECB (error!!!) • An optional timeout can be specified in case the ECB is not signaled within the specified time period 7
Semantics of ECB • Multiple tasks can wait for an ECB. – Only the highest priority task (HPT) is made ready to run when the ECB is signaled. • When a ECB is used as a semaphore, tasks can both wait and signal the ECB. 8
The use of ECB • A building block to implement services such as – – Semaphore Mutual Exclusion Semaphore Message Mailbox Message Queue • All ECB functions only consider how to manipulate data structures. Caller must consider synchronization issues 9
ECB data structure 10
ECB data structure Type of event control block . OSEvent. Type. OSEvent. Grp ~ OSRdy. Grp . OSEvent. Cnt Semaphore Count… . OSEvent. Ptr Pointer to message or queue structure 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 . . . ~ OSRdy. Tbl 55 54 53 52 51 50 49 48 63 62 61 60 59 58 57 56 “red” fields are Initialized by OS_Event. Wait. List. Init ~: is “similar to” 11
OSEvent. Type OSEvent. Grp OSEvent. Cnt OSEvent. Ptr OSEvent. Tbl[] OS_EVENT_TYPE_SEM OS_EVENT_TYPE_MUTEX 0 x 00 cnt prio OS_MUTEX_AVAILABLE NULL 0 x 00 … 0 x 00 OS_EVENT_TYPE_QM OS_EVENT_TYPE_MBOX 0 x 00 cnt 0 x 00 Point to Q Point to msg 0 x 00 … 0 x 00 12
ECB Functions • OS_Event. Wait. List. Init() Initialize an ECB • OS_Event. Task. Rdy() Make a task ready • OS_Event. Task. Wait() Put the task to sleep • OS_Event. TO() Make a task ready 13
1 1 ready queue 1 1 2. OS_XXX_Post Task A (OS_Event_Task. Rdy) ECB (waiting queue) 1 1. OS_XXX_Pend (OS_Event_Task. Wait) Task B 5 14
1 1 ready queue 1 1 OS_XXX_Post Task A (OS_Event_Task. Rdy) ECB (waiting queue) 1 1. OS_XXX_Pend (OS_Event_Task. Wait) Task B 5 2. OS_Event. TO 15
OS_Event. Wait. List. Init() "loop unrolling" 16
OS_Event. Task. Rdy() • This function is called by the POST functions for a semaphore, a mutex, a message mailbox or a message queue when the ECB is signaled. • OS_Event. Task. Rdy() removes the highest priority task from the wait list of the ECB and makes this task ready to run. 17
OS_Event. Task. Rdy() - 1 Waiting Queue Event. Grp Event. Tbl Ready Queue 1 OSRdy. Grp 1 1 1 OSRdy. Tbl 1 18
OS_Event. Task. Rdy() - 2 Waiting Queue Event. Grp Ready Queue OSRdy. Grp 1 Event. Tbl 1 1 OSRdy. Tbl 1 19
OS_Event. Task. Rdy() - 3 Waiting Queue Event. Grp Ready Queue OSRdy. Grp 1 Event. Tbl 1 1 1 OSRdy. Tbl 1 1 1 20
OS_Event. Task. Rdy() - 4 OSTCBDly=? for OSTask. Del() 1 OSTCBEvent. Ptr OSTCBStat 1 1 Task Control Block (TCB) Event Control Block (ECB) 21
OS_Event. Task. Rdy() - 5 OSTCBDly=? 1 OSTCBEvent. Ptr OSTCBStat 1 1 Task Control Block (TCB) Event Control Block (ECB) 22
OS_Event. Task. Rdy() - 6 OSTCBDly= 0 1 OSTCBEvent. Ptr OSTCBStat 1 1 ≒ Rdy Task Control Block (TCB) Event Control Block (ECB) 23
OS_Event. Task. Rdy() INT 8 U OS_Event. Task. Rdy (OS_EVENT *pevent, void *msg, INT 8 U msk) { OS_TCB *ptcb; Find highest priority task INT 8 U x, y, bitx, bity, prio; waiting for message y = OSUn. Map. Tbl[pevent->OSEvent. Grp]; bity = OSMap. Tbl[y]; x = OSUn. Map. Tbl[pevent->OSEvent. Tbl[y]]; bitx = OSMap. Tbl[x]; prio = (INT 8 U)((y << 3) + x); if ((pevent->OSEvent. Tbl[y] &= ~bitx) == 0 x 00) pevent->OSEvent. Grp &= ~bity; ptcb = OSTCBPrio. Tbl[prio]; ptcb->OSTCBDly = 0; ptcb->OSTCBEvent. Ptr = (OS_EVENT *)0; ptcb->OSTCBMsg = msg; ptcb->OSTCBStat &= ~msk; if (ptcb->OSTCBStat == OS_STAT_RDY) { OSRdy. Grp |= bity; OSRdy. Tbl[y] |= bitx; } return (prio); } Remove this task from the waiting list Prevent OSTime. Tick() from readying task Unlink ECB from this task Clear bit associated with event type Set the task ready to run if the task is not suspended 24
OS_Event. Task. Wait() • This function is called by the PEND functions for a semaphore, a mutex, a message mailbox or a message queue when a task must wait on an ECB. • It removes the current task from the ready list and places it in the wait list of the ECB. 25
OS_Event. Task. Wait() - 1 Waiting Queue Event. Grp Ready Queue OSRdy. Grp 1 Event. Tbl 1 1 1 OSRdy. Tbl 1 1 1 26
OS_Event. Task. Wait() - 2 Waiting Queue Event. Grp Ready Queue OSRdy. Grp 1 Event. Tbl 1 1 OSRdy. Tbl 1 1 1 27
OS_Event. Task. Wait() - 3 Waiting Queue Event. Grp Event. Tbl Ready Queue 1 OSRdy. Grp 1 1 1 OSRdy. Tbl 1 1 1 28
OS_Event. Task. Wait() void OS_Event. Task. Wait (OS_EVENT *pevent) Task no longer { ready OSTCBCur->OSTCBEvent. Ptr = pevent; if ((OSRdy. Tbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBit. X) == 0 x 00) { OSRdy. Grp &= ~OSTCBCur->OSTCBBit. Y; } pevent->OSEvent. Tbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBit. X; pevent->OSEvent. Grp |= OSTCBCur->OSTCBBit. Y; } Put task in waiting list 29
OS_Event. TO() • OS_Event. TO = OS-Event-Time-Out • This function is called by the PEND functions for a semaphore, a mutex, a message mailbox or a message queue when the ECB is not signaled within the specified timeout period. 30
Usage: OS_Event. Task. Rdy() Taski Taskj xxx_post() xxx_pend( 0 ) 31
Usage: OS_Event. TO() Taski Taskj Waiting queue Ready queue xxx_post() xxx_pend( 3 ) xxx_post() xxx_pend( 0 ) 3 0 1 2 32
OS_Event. TO() void OS_Event. TO (OS_EVENT *pevent) { if ((pevent->OSEvent. Tbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBit. X) == 0 x 00) { Remove the task pevent->OSEvent. Grp &= ~OSTCBCur->OSTCBBit. Y; from the waiting list } of the ECB OSTCBCur->OSTCBStat = OS_STAT_RDY; OSTCBCur->OSTCBEvent. Ptr = (OS_EVENT *)0; } 33
- Slides: 33