Synchronization Akos Ledeczi EECE 6354 Fall 2019 Vanderbilt
Synchronization Akos Ledeczi EECE 6354, Fall 2019 Vanderbilt University
Semaphores • They work for synchronization too • ISR to Task or • Task to Task
Unilateral Rendezvous • Task calling Pend() does not need to know about the details: the Pend() call will return when the event has occurred • Maximizes use of CPU; no busy waiting • Event (i. e. , Post()) will cause the waiting task to run immediately (assuming it has the highest priority)
Credit Tracking • Semaphore accumulates the number of times Post() has been called /without a corresponding Pend()/
Broadcasting • • Multiple tasks waiting on a semaphore OS_OPT_POST_ALL All waiting tasks become ready to run Care must be taken because some of the tasks may not have called Pend() yet
Task Semaphores • • In µC/OS-III each task has a built-in semaphore More efficient OSTask. Sem. Pend(); OSTask. Sem. Post(); etc. Post()-er (ISR or Task) needs to know which task to notify
Bilateral Rendezvous void Task 1(void *p_arg) { … OSTask. Sem. Post(&Task 2_TCB, OS_OPT_POST_1, &err); OSTask. Sem. Pend(0, OS_OPT_PEND_BLOCKING, &ts, &err); … } void Task 2(void *p_arg) { … OSTask. Sem. Post(&Task 1_TCB, OS_OPT_POST_1, &err); OSTask. Sem. Pend(0, OS_OPT_PEND_BLOCKING, &ts, &err); … } • Only between tasks, as an ISR cannot Pend()
Event Flags • • • When tasks need to synchronize on multiple events When any of the events is enough: disjunctive synchronization (OR) When all events are needed: conjunctive synchronization (AND) OSFlag? ? ? (); OSFlag. Pend. Get. Flags. Rdy(): which flags caused task to become ready
Event. Flags Example #define TEMP_LOW #define BATT_LOW #define SW_PRESSED (OS_FLAGS)0 x 01 (OS_FLASG)0 x 02 (OS_FLAGS)0 x 04 OS_FLAG_GRP My. Event. Flag. Grp; void main() { … OSFlag. Create(&My. Event. Flag. Grp, “My flags”, 0, &err); … } void Task 1(void *p_arg) { … for( ; ; ) { OSFlag. Pend(&My. Event. Flag. Grp, TEMP_LOW + BATT_LOW, 0 OS_OPT_PEND_FLAG_SET_ANY, ts, &err); … } } void Task 2(void *p_arg) { … for ( ; ; ) { OSFlag. Post(&My. Event. Flag. Grp, BATT_LOW, OS_OPT_POST_FLAG_SET, &err); } … }
Status and Transient Events • Typically: – Status info monitored by one task, handled by another task using a non -blocking call – A transient event is generated by an ISR or task and handled and consumed by a task using a blocking call
Event Flag Internals struct os_flag_grp { OS_OBJ_TYPE CPU_CHAR OS_PEND_LIST OS_FLAGS CPU_TS }; Type *Name. Ptr Pend. List; Flags TS OSFlag. Post(&flag. Grp, (OS_FLAGS)0 x 0 C, OS_OPT_FLAG_SET, &err); • Pend list is not in priority order as all tasks need to be looked at anyways • Look at code on the left: • If OS_OPT_FLAG_SET and flags contain 0 x 03, result will be 0 x 0 F • If OS_OPT_FLAG_CLR and flags contain 0 x 0 F, result will be 0 x 03
Synchronizing Multiple Tasks
- Slides: 12