Real Time Operating Systems Mutual Exclusion, Synchronization & Intertask Communication Course originally developed by Maj Ron Smith
Outline Mutual Exclusion, Synchronization & Intertask Communications Semaphores Message Mailboxes & Queues Event Flags Task Dependency Issues Priority Inversion Priority Inheritance / Ceiling Priority Protocols Mutual Exclusion Semaphores 25-Nov-15 2 Dr Alain Beaulieu
Mutual Exclusion Recall that in a preemptive system, shared resources, including data stores, must often be protected by mutual exclusion Further recall the following techniques to address mutual exclusion in μC/OS: disabling/enabling interrupts disabling scheduling using semaphores Exactly what seemingly simple problem does the semaphore solve? 25-Nov-15 3 Dr Alain Beaulieu
Task Synchronization Dependence between tasks is not always a “data” dependency (shared resource) It is also possible that tasks are temporally dependent, meaning that the execution, or continued execution, of one task depends upon the completion, or partial completion, of another task(s) Recall that this type of dependency is often modeled as a rendezvous unilateral, bilateral, … 25-Nov-15 4 Dr Alain Beaulieu
Intertask Communication One way in which tasks can communicate with each other is through shared data stores This introduces the mutual exclusion problem discussed previously An alternate method is for tasks to send each other messages often modeled as mailboxes and queues Does messaging remove the intertask dependency? 25-Nov-15 5 Dr Alain Beaulieu
Semaphores Task or Task ISR OSSemPost( ) OSSemAccept( ) OSSemCreate( ) OSSemDel( ) OSSemPost( ) OSSemAccept( ) OSSemPend( ) OSSemQuery( ) Used for mutual exclusion or synchronization 25-Nov-15 6 Dr Alain Beaulieu
Message Mailbox Task ISR OSMboxPost( ) OSMboxPostOpt( ) OSMboxAccept( ) OSMboxCreate( ) OSMboxDel( ) OSMboxPost( ) OSMboxPostOpt( ) OSMboxAccept( ) OSMboxPend( ) OSMboxQuery( ) Message 25-Nov-15 7 Dr Alain Beaulieu
Message Queues Task ISR OSQFlush OSQPost( )/PostFront( ) OSQPostOpt( ) OSQAccept( ) OSQCreate( ) OSQDel( ) OSQFlush OSQPost( )/PostFront( ) OSQPostOpt( ) OSQAccept( ) OSQPend( ) OSQQuery( ) Message 25-Nov-15 8 Dr Alain Beaulieu
Event Flags* Task ISR OSFlagPost( ) OSFlagAccept( ) OSFlagQuery( ) OSFlagCreate( ) OSFlagDel( ) OSFlagPost( ) OSFlagAccept( ) OSFlagPend( ) OSFlagQuery( ) Event Flag Group *See example in handout 25-Nov-15 9 Dr Alain Beaulieu
Task Independence The assumption that tasks are independent is unreasonable for any meaningful system tasks share common resources via semaphores tasks often must synchronize with each other tasks often must communicate with each other This implies that a task(s) may suspend pending some future event which is dependent upon one or more other tasks How will this dependence affect task execution on a priority-based preemptive kernel? 25-Nov Dr Alain Beaulieu
Priority Inversion Priority inversion can occur when a high and a low priority task share a common resource the low priority task gets exclusive access to the shared resource the higher priority task preempts the lower priority task but is blocked pending release of the shared resource meanwhile a medium priority task preempts the lower priority task, thus further delaying the execution of the high priority task since the medium task is guaranteed priority service over the blocked higher priority task, we get priority inversion 25-Nov Dr Alain Beaulieu
Illustrated Priority Inversion Time low highmedium (1) (2) (3) (4) (9) (10) (7) (5) (6) (8) (11) medium priority task preempts low (and high) priority tasks low priority task locks shared resource high priority task blocks pending release of shared resource 25-Nov Dr Alain Beaulieu
Priority Inheritance Simple priority inheritance is a technique for avoiding priority inversion the priority of a task gaining access to a shared resource dynamically inherits the priority of the highest priority task sharing the resource inheritance occurs when the blocking event occurs Theorem : if priority inheritance is employed, the number of times a task can be blocked by lower priority tasks is limited by the lessor of: K - the number of blocking critical sections; or N - the number of lower priority tasks 25-Nov Dr Alain Beaulieu
Transitive Blocking Using simple priority inheritance to handle the priority inversion problem, can result in tasks being transitively blocked by multiple other tasks Transitive blocking means that a series of blocking events occur wherein lower priority tasks block, in succession, block higher priority tasks Although the probability of these transitive events is very low, it is possible in the worst-case! 25-Nov Dr Alain Beaulieu
Illustrated Transitive Blocking The graph below illustrates transitive priority inheritance among 3 tasks & 2 resources 024 T1T1 T3T3 T2T2 68 =3 =2 =1 10 =1 L(R 1 ) L(R 2 ) L(R 1 )L(R 2 ) =1 U(R 2 ) =3 =2 U(R 2 )U(R 1 ) =2 U(R 1 ) =3 25-Nov Dr Alain Beaulieu
Deadlock Another serious issue that arises with shared resources is deadlock While the use of a simple priority inheritance algorithm addresses priority inversion, it does not help prevent deadlock Think about how deadly deadlock might be to a real-time system! 25-Nov Dr Alain Beaulieu
Illustrated Deadlock Given: T= {(3.5, 1; R 1 (0.2), R 2 (0.7)), (4,1), (5, 2, 7; R 1 (0.8),R 2 (0.1)) } 024 T1T1 T3T3 T2T L(R 1 ) - requests R 1 & blocks L(R 2 ) - requests R 2 & blocks - forever, T 1 now blocks forever as well L(R 2 ) L(R 1 ) 25-Nov Dr Alain Beaulieu
Yet another view of deadlock From this “wait-for” graph, we see that the closed loop is also evidence of a deadlock 25-Nov Dr Alain Beaulieu T1T1 T2T2 R1R1 R2R2
Ceiling Priority Protocols A class of resource sharing algorithms entitled Ceiling Priority Protocols are introduced as an alternative to simple priority inheritance to: eliminate transitive blocking for any given task only a single blocking event may occur eliminate deadlock a task holding one resource may not claim another resource that could lead to circular lock/requests 25-Nov Dr Alain Beaulieu
Original Ceiling Priority Protocol Each task has a static default priority Each resource has a static ceiling value, equal to the maximum priority of the processes which use it Each task has a dynamic priority, equal to the maximum of its own static priority and any it inherits from ceiling(s) due to blocking higher priority tasks A task can lock a resource only if its dynamic priority is higher than the ceiling of any currently locked resource (excluding of course any it has locked) 25-Nov Dr Alain Beaulieu
Immediate Ceiling Priority Protocol Each task has a static default priority assigned (using some priority assignment - maybe DMPO) Each resource has a static ceiling value, equal to the maximum priority of the processes which use it Each task also has a dynamic priority, equal to the maximum of its own static priority and the ceiling values of any resources it has locked inheritance happens immediately upon locking the resource 25-Nov Dr Alain Beaulieu
Mutual Exclusion Semaphores When a task requests a OSMutexPend( ) on a mutex that is currently held by a lower priority task, the system call raises the priority of the lower priority task to that of the mutex, thus causing a context switch. Similarly when this task releases the mutex with the OSMutexPost( ), this system call restores the priority of the lower priority task, and … Task OSMutexCreate( ) OSMutexDel( ) OSMutexPost( ) OSMutexAccept( ) OSMutexPend( ) OSMutexQuery( ) Note how μC/OS’ unique priority assignment constrains the use of mutexes. *See example in handout 25-Nov Dr Alain Beaulieu
Questions Is the μC/OS Mutual Exclusion Semaphore (Mutex) an implementation of simple priority inheritance, or immediate ceiling priority protocol? What are the implications of your answer? 25-Nov Dr Alain Beaulieu
References [1] Liu, J.W.S., “Real-Time Systems”, Prentice- Hall, [2] Labrosse, J.J., “MicroC/OS-II” 1 st and 2 nd Editions (1999, 2002) [3] Burns, A. and Wellings, A., “Real-Time Systems and Programming Languages”, Chapter 13, Addison Wesley, Nov Dr Alain Beaulieu