Synchronization 2 IN 60 Realtime Architectures for automotive

  • Slides: 51
Download presentation
Synchronization 2 IN 60: Real-time Architectures (for automotive systems) Mike Holenderski, m. holenderski@tue. nl

Synchronization 2 IN 60: Real-time Architectures (for automotive systems) Mike Holenderski, m. [email protected] nl

Goals for this slide set • Describe different dependencies which may exist between tasks

Goals for this slide set • Describe different dependencies which may exist between tasks • Describe different methods for synchronizing dependent tasks, and explain how to apply them • Describe the priority inversion and deadlock problems, and how to address them • Explain how to implement periodic tasks using semaphores Mike Holenderski, m. [email protected] nl 2

Outline • Synchronization requirements – Mutual exclusion – Precedence constraints • Mutexes – Problems:

Outline • Synchronization requirements – Mutual exclusion – Precedence constraints • Mutexes – Problems: priority inversion & deadlock – Solutions: Priority Calling Protocol & Stack Resource Policy • Semaphores – Example: implementing periodic tasks Mike Holenderski, m. [email protected] nl 3

Synchronization problem • Mutual exclusion: – A resource can be used by at most

Synchronization problem • Mutual exclusion: – A resource can be used by at most one task or ISR at a time • Precedence constraints: – Tasks or ISRs must execute in a particular order • Problem: Co-ordinate execution of a given concurrent program such that no erroneous interleavings are possible Mike Holenderski, m. [email protected] nl 4

Example: mutual exclusion (disabling interrupts) • Implement atomicity by disabling interrupts • Problem: busy

Example: mutual exclusion (disabling interrupts) • Implement atomicity by disabling interrupts • Problem: busy waiting inside of conversion with non-preemptive execution w. r. t. tasks and ISRs int ATDRead. Channel(. . . ) {. . . OS_ENTER_CRITICAL(); “do the conversion”; OS_EXIT_CRITICAL(); . . . } void Task 1(void) {. . . ATDRead. Channel(PAD 13); . . . } void Task 2(void) {. . . ATDRead. Channel(PAD 14); . . . } – Higher priority tasks not sharing resources are penalized – May lead to missed interrupts Mike Holenderski, m. [email protected] nl 5

Example: mutual exclusion (disabling scheduler) • Implement atomicity by disabling scheduler • Problem: busy

Example: mutual exclusion (disabling scheduler) • Implement atomicity by disabling scheduler • Problem: busy waiting inside of conversion with non-preemptive execution w. r. t. tasks int ATDRead. Channel(. . . ) {. . . OSSched. Lock(); “do the conversion”; OSSched. Unlock(); . . . } void Task 1(void) {. . . ATDRead. Channel(PAD 13); . . . } void Task 2(void) {. . . ATDRead. Channel(PAD 14); . . . } – Higher priority tasks not sharing resources are penalized Mike Holenderski, m. [email protected] nl 6

Mutual exclusion: spot the bug • Implement atomicity by checking a global flag •

Mutual exclusion: spot the bug • Implement atomicity by checking a global flag • Problem: if Task 1 has higher priority than Task 2 and preempts Task 2 after Task 2 has set avail to false, then Task 1 will busy-wait forever, preventing Task 2 to set avail to true • Solution: suspend Task 1 when avail is false, allowing Task 2 to set it to true Mike Holenderski, m. [email protected] nl int avail = true; int ATDRead. Channel(. . . ) {. . . while (!avail) {} avail = false; “do the conversion”; avail = true; . . . } void Task 1(void) {. . . ATDRead. Channel(PAD 13); . . . } void Task 2(void) {. . . ATDRead. Channel(PAD 14); . . . } 7

Precedence constraints: spot the bug • Task 2 senses the light. Every time that

Precedence constraints: spot the bug • Task 2 senses the light. Every time that the value is larger than some threshold, Task 1 toggles a led • Problem: if Task 1 has a higher priority than Task 2, Task 1 will busy-wait and Task 2 will never run • Solution: have Task 1 suspend until x is true, or swap the task priorities Mike Holenderski, m. [email protected] nl 8 int x = false; int light; void Task 1(void) while (!x) {} x = false; if (light > Threshold) { Toggle. Led(LED_D 24); } } void Task 2(void) light = ATDRead. Channel(PAD 14); x = true; }

Synchronization primitives • Primitives for synchronizing tasks and ISRs: check for a condition and

Synchronization primitives • Primitives for synchronizing tasks and ISRs: check for a condition and wait until the condition is satisfied – Examples of conditions: • a shared resource is available • a signal from ISR has arrived • another task has arrived Mike Holenderski, m. [email protected] nl 9

Synchronization primitives • Two options for waiting: suspend or busy-wait – Suspend: execute the

Synchronization primitives • Two options for waiting: suspend or busy-wait – Suspend: execute the check and suspension atomically – Busy waiting is only reasonable if • preemption is allowed and we are waiting for a higher priority task or ISR, or • it involves another piece of hardware (e. g. multi-core, sensors). Mike Holenderski, m. [email protected] nl 10

Synchronization primitives • Blocking due to mutual exclusion: üDisable interrupts üDisable scheduler – Mutexes

Synchronization primitives • Blocking due to mutual exclusion: üDisable interrupts üDisable scheduler – Mutexes – Semaphores • Blocking due to precedence constraints: – Semaphores Mike Holenderski, m. [email protected] nl 11

Outline • Synchronization requirements – Mutual exclusion – Precedence constraints • Mutexes – Problems:

Outline • Synchronization requirements – Mutual exclusion – Precedence constraints • Mutexes – Problems: priority inversion & deadlock – Solutions: Priority Calling Protocol & Stack Resource Policy • Semaphores – Example: implementing periodic tasks Mike Holenderski, m. [email protected] nl 12

Mutex • Mutex guards a shared resource, allowing only one task to access it

Mutex • Mutex guards a shared resource, allowing only one task to access it at a time • Tasks can acquire and release a mutex void Task(void) {. . . (* acquire mutex *); (* execute critical section *); (* release mutex *); . . . } • While a task is holding a mutex, no other task is able to acquire it Mike Holenderski, m. [email protected] nl 13

Dining philosophers problem Deadlock Mike Holenderski, m. holenderski@tue. nl 14

Dining philosophers problem Deadlock Mike Holenderski, m. [email protected] nl 14

Deadlock problem • Deadlock can occur when resources are acquired in nested fashion and

Deadlock problem • Deadlock can occur when resources are acquired in nested fashion and there is a cyclic dependency Mike Holenderski, m. [email protected] nl OS_EVENT* mutex 1; OS_EVENT* mutex 2; void Task 1(void* p. Arg) {. . . OSMutex. Pend(mutex 1, 0, &err); OSMutex. Pend(mutex 2, 0, &err); (* a critical section *) OSMutex. Post(mutex 2); OSMutex. Post(mutex 1); . . . } void Task 2(void* p. Arg) {. . . OSMutex. Pend(mutex 2, 0, &err); OSMutex. Pend(mutex 1, 0, &err); (* a critical section *) OSMutex. Post(mutex 1); OSMutex. Post(mutex 2); . . . } 15

Example: deadlock • Consider a system comprised of tasks 1 and 2 – 1

Example: deadlock • Consider a system comprised of tasks 1 and 2 – 1 and 2 both use resources r 1 and r 2 – 1 first locks r 1 and subsequently r 2 – 2 first locks r 2 and subsequently r 1 • Problem: deadlock may occur Mike Holenderski, m. [email protected] nl 16

Avoiding deadlock • Avoid nested critical sections – in principle, no Pend operations between

Avoiding deadlock • Avoid nested critical sections – in principle, no Pend operations between Pend(m)…Post(m) • Acquire all required resources at once (atomically) – Let Pend({a, b, c, …}) be an indivisible operation when there is a danger of deadlock, acquiring resources a, b, c, … atomically • Use a fixed order of Pend() operations – Pend(m); Pend(n); . . in one process may deadlock with Pend(n); Pend(m); . . . in another process – Solution: acquire resources in a fixed order Mike Holenderski, m. [email protected] nl 17

Dining philosophers problem Forks should be picked up in the order: 1, 2, 3

Dining philosophers problem Forks should be picked up in the order: 1, 2, 3 1 2 3 Mike Holenderski, m. [email protected] nl 18

Avoiding deadlock • Avoid nested critical sections – in principle, no Pend operations between

Avoiding deadlock • Avoid nested critical sections – in principle, no Pend operations between Pend(m)…Post(m) • Acquire all required resources at once (atomically) – Let Pend({a, b, c, …}) be an indivisible operation when there is a danger of deadlock, acquiring resources a, b, c, … atomically • Use a fixed order of Pend() operations – Pend(m); Pend(n); . . in one process may deadlock with Pend(n); Pend(m); . . . in another process – Solution: acquire resources in a fixed order • Use an appropriate Resource Access Protocol – E. g. Stack Resource Policy (SRP) • In general: avoid cyclic dependencies! Mike Holenderski, m. [email protected] nl 19

Priority inversion • A low priority job obtains a resource; a high priority job

Priority inversion • A low priority job obtains a resource; a high priority job waits on its release • A middle priority job pre-empts the low priority job during resource access – the high priority job now waits on the middle priority job. . . and effectively has the low priority while waiting L(r) U(r) task h priority inversion task l L(r) U(r) Mike Holenderski, m. [email protected] nl task m task l “unbounded” priority inversion L(r) U(r)

Priority inversion • A pair of alternating middle priority jobs can block the high

Priority inversion • A pair of alternating middle priority jobs can block the high priority job “indefinitely” – “unbounded” priority inversion: • example: Mars rover; see article. • Resource access protocol: – Guarantee mutual exclusion (e. g. mutexes) – Resolve other problems, such as priority inversion – At least bound the inversion time – Adhere to the task priorities as closely as possible Mike Holenderski, m. [email protected] nl 21

Resource access protocols: Priority Calling Protocol • Protocol – Each mutex has a priority,

Resource access protocols: Priority Calling Protocol • Protocol – Each mutex has a priority, which is used when accessing the mutex: • When the mutex is already acquired and a higher priority task attempts to acquire the mutex, then the priority of the task owning the mutex is raised to the mutex priority • Mutex priority must be higher than any of the tasks competing for the mutex Mike Holenderski, m. [email protected] nl 22

Resource access protocols: Priority Calling Protocol • Properties – Avoids “unbounded” priority inversion –

Resource access protocols: Priority Calling Protocol • Properties – Avoids “unbounded” priority inversion – Suffers from deadlock! • Used in μC/OS-II for implementing mutexes Mike Holenderski, m. [email protected] nl 23

Priority Calling Protocol Mike Holenderski, m. holenderski@tue. nl 24

Priority Calling Protocol Mike Holenderski, m. [email protected] nl 24

Priority Calling Protocol Mike Holenderski, m. holenderski@tue. nl 25

Priority Calling Protocol Mike Holenderski, m. [email protected] nl 25

Resource access protocols: Stack Resource Policy (SRP) • Protocol – Assign to each mutex

Resource access protocols: Stack Resource Policy (SRP) • Protocol – Assign to each mutex a ceiling, equal (or higher) to the maximum priority of any task that can acquire it – Scheduler keeps track of the system ceiling, equal to the maximum ceiling of any mutex currently acquired by any task – A task can only start executing if • it has the highest priority among ready tasks, and • its priority is higher than the current system ceiling Mike Holenderski, m. [email protected] nl 26

Resource access protocols: Stack Resource Policy (SRP) • Properties – Avoids deadlock – Priority

Resource access protocols: Stack Resource Policy (SRP) • Properties – Avoids deadlock – Priority inversion limited to at most one critical section of a lower priority task – Simplementation: • Can reuse the ready queue (used by the scheduler) for storing the tasks blocked on a mutex Mike Holenderski, m. [email protected] nl 27

Stack Resource Policy Mike Holenderski, m. holenderski@tue. nl 28

Stack Resource Policy Mike Holenderski, m. [email protected] nl 28

Stack Resource Policy Task 2 is not blocked while Task 3 accesses resource :

Stack Resource Policy Task 2 is not blocked while Task 3 accesses resource : -) Mike Holenderski, m. [email protected] nl 29

Mutexes in μC/OS-II • Mutexes in μC/OS-II implement the Priority Calling Protocol • Mutexes

Mutexes in μC/OS-II • Mutexes in μC/OS-II implement the Priority Calling Protocol • Mutexes cannot be used by ISRs • Mutex is created using OS_EVENT* m = OSMutex. Create(prio, &err); – Mutex is assigned a priority prio • prio must be set to a priority higher than any task accessing mutex m Mike Holenderski, m. [email protected] nl 30

Mutexes in μC/OS-II • Tasks can acquire mutex m using OSMutex. Pend(m, timeout, &err);

Mutexes in μC/OS-II • Tasks can acquire mutex m using OSMutex. Pend(m, timeout, &err); – If the m is available it is immediately acquired – If the m is already acquired, the task is suspended until another task releases m • Tasks with a higher priority than prio will not be blocked by the lower priority tasks while they are using m – Since prio is higher than the priority of any task using m, at most one task can be suspended on m – If timeout > 0 and m does not become available within that time, an error is returned indicating that m could not be granted. If timeout is 0, then OSMutex. Pend() will wait indefinitely until m is available. – &err is a pointer to an integer where the error code is returned Mike Holenderski, m. [email protected] nl 31

Mutexes in μC/OS-II • Tasks can release mutex m using OSMutex. Post(m); – If

Mutexes in μC/OS-II • Tasks can release mutex m using OSMutex. Post(m); – If there is any other task waiting for m, that task is made ready and the scheduler is invoked Mike Holenderski, m. [email protected] nl 32

Disabling the scheduler vs. mutexes in μC/OS-II Using mutexes Disabling the scheduler OS_EVENT* mutex;

Disabling the scheduler vs. mutexes in μC/OS-II Using mutexes Disabling the scheduler OS_EVENT* mutex; void Task(void) {. . . OSSched. Lock(); (* a critical section *) Os. Sched. Unlock(); . . . } void Task(void) { INT 8 U err; . . . OSMutex. Pend(mutex, 0, &err); (* a critical section *) OSMutex. Post(mutex); . . . } void main(void) { INT 8 U err; . . . mutex = OSMutex. Create(prio, &err); . . . } Mike Holenderski, m. [email protected] nl 33

Evaluation: disabling interrupts • Pros: – Avoids deadlock and “unbounded” priority inversion – Simplementation

Evaluation: disabling interrupts • Pros: – Avoids deadlock and “unbounded” priority inversion – Simplementation (low memory processor overhead) – Simple timing analysis • Cons: – May lead to unnecessarily long blocking times • In particular, for higher priority tasks that do not need the shared resource. – May lead to missed interrupts Mike Holenderski, m. [email protected] nl 34

Evaluation: disabling the scheduler • Pros: – Simplementation (low memory processor overhead) – Simple

Evaluation: disabling the scheduler • Pros: – Simplementation (low memory processor overhead) – Simple timing analysis • Cons: – May lead to unnecessarily long blocking times • In particular, for higher priority tasks that do not need the shared resource. – If ISRs use shared resources, then atomicity is not guaranteed Mike Holenderski, m. [email protected] nl 35

Evaluation: mutexes • Pros: – Allow handling of interrupts • Reduce processor blocking to

Evaluation: mutexes • Pros: – Allow handling of interrupts • Reduce processor blocking to just the administration of the mutual exclusion primitives – Higher priority tasks not sharing the resource guarded by the critical section are not affected • Cons: – Not allowed in ISRs – Elaborate implementation • Need to maintain the task suspended on a mutex (μC/OS-II) – Introduces possibility for deadlock • Can be prevented with the right resource access protocol Mike Holenderski, m. [email protected] nl 36

Outline • Synchronization requirements – Mutual exclusion – Precedence constraints • Mutexes – Problems:

Outline • Synchronization requirements – Mutual exclusion – Precedence constraints • Mutexes – Problems: priority inversion & deadlock – Solutions: Priority Calling Protocol & Stack Resource Policy • Semaphores – Example: implementing periodic tasks Mike Holenderski, m. [email protected] nl 37

Semaphores • Conceived by Edsger W. Dijkstra (TU/e, 1965) • Semaphore s is an

Semaphores • Conceived by Edsger W. Dijkstra (TU/e, 1965) • Semaphore s is an integer with initial value s 0 and atomic operations P(s) and V(s). – Task executing P(s) is said to “try to acquire semaphore s” – P(s) stands for “prolaag”, i. e. portmanteau for “probeer te verlagen” – Task executing V(s) is said to “release semaphore s” – V(s) stands for “verhoog” Mike Holenderski, m. [email protected]ue. nl 38

Semaphores • The effect of these operations is defined as follows: – P(s): <

Semaphores • The effect of these operations is defined as follows: – P(s): < await(s>0); s = s-1 > – V(s): < s = s+1 > • (here we used “< >” to denote atomicity) • await: a statement to indicate suspension until a condition is met • The s>0 check and s = s-1 must be executed atomically • A process that executes P(s) is suspended until s>0 • A process executing V(s) possibly releases suspended processes Mike Holenderski, m. [email protected] nl 39

Semaphores • General assumptions: – atomic execution of P and V • If several

Semaphores • General assumptions: – atomic execution of P and V • If several processes simultaneously invoke a P or V operation on the same semaphore, the operations will occur sequentially in an arbitrary order. – arbitrary selection of process to proceed: • If more than one process is waiting inside a P operation on the same semaphore and the semaphore becomes positive (because of the execution of a V), one of the waiting processes is selected arbitrarily to complete the P operation. Mike Holenderski, m. [email protected] nl 40

Semaphores • Specific assumptions for Real-Time Systems: – specific selection of process to proceed:

Semaphores • Specific assumptions for Real-Time Systems: – specific selection of process to proceed: • … the process with the highest priority among the waiting processes is selected to complete the P operation. Mike Holenderski, m. [email protected] nl 41

Example: synchronizing tasks using semaphores • Mutual exclusion: – Assume a resource guarded by

Example: synchronizing tasks using semaphores • Mutual exclusion: – Assume a resource guarded by semaphore s – Each task sharing resource guarded by s contains: P(s) /* use resource */ V(s) – Initialization: s = 1 • Precedence (enforced limitations on order, where the triggered task waits for a triggering task): – – Assume synchronization based on s Triggering task: V(s) Triggered task: P(s) Initialization: s = 0 Mike Holenderski, m. [email protected] nl 42

Semaphores in μC/OS-II • Semaphores can be used by tasks and ISRs – With

Semaphores in μC/OS-II • Semaphores can be used by tasks and ISRs – With the exception of OSSem. Pend()(task only) • Semaphore is created using OS_EVENT* s = OSSem. Create(value); – Semaphore is not assigned a priority – value is the initial value of s Mike Holenderski, m. [email protected] nl 43

Semaphores in μC/OS-II • Tasks can acquire one unit of semaphore s using OSSem.

Semaphores in μC/OS-II • Tasks can acquire one unit of semaphore s using OSSem. Pend(s, timeout, &err); – If the value of s > 0, the semaphore is decremented and task continues – If the value of s = 0, the task is suspended – Several tasks may be blocked on the same semaphore • They will be released according to their priority (highest first) – If timeout > 0 and s was not granted before that, an error is returned – &err is a pointer to an integer where the error code is returned – Note: this is the P(s) operation Mike Holenderski, m. [email protected] nl 44

Semaphores in μC/OS-II • Tasks can release semaphore s using OSSem. Post(s); – If

Semaphores in μC/OS-II • Tasks can release semaphore s using OSSem. Post(s); – If there is any other task waiting for s, that task is made ready and the scheduler is invoked – Note: this is the V(s) operation Mike Holenderski, m. [email protected] nl 45

Example: implementing periodic tasks • Periodic task τi is specified by: – priority i,

Example: implementing periodic tasks • Periodic task τi is specified by: – priority i, phasing φi , period Ti • Standard μC/OS-II does not support periodic tasks – These are added by the RELTEQ extension Mike Holenderski, m. [email protected] nl 46

Periodic task implementation • Two options: – Create a new task context upon each

Periodic task implementation • Two options: – Create a new task context upon each job arrival – Create a task context ✓ once, and let jobs be the iterations of a while loop. Mike Holenderski, m. [email protected] nl 47 void Task(void (*f)(void)) {. . . while (true) { OSTask. Wait. Period(); f(); } } void OSTime. Tick(void) {. . . if (* Task_i period expired *) { (* signal Task_i *) }. . . } void main(void) {. . . OSTask. Create. Periodic(fi, Ti, φi, s, i); . . . }

Periodic task implementation • Synchronize loop iterations using OSTime. Dly() • Suffers from large

Periodic task implementation • Synchronize loop iterations using OSTime. Dly() • Suffers from large jitter – Due to interference between OSTime. Get() and OSTime. Dly() Mike Holenderski, m. [email protected] nl 48 void Task(void (*f)(void)) { int k = 0; . . . while (true) { now. OSTask. Wait. Period(); = OSTime. Get(); f(); OSTime. Dly(φi + k∗Ti - now); } f(); } k = k + 1; void } OSTime. Tick(void) { }. . . void if (* OSTime. Tick(void) Task_i period expired { *) {. . . (* signal Task_i *) }if (* Task_i period expired *) {. . . (* signal Task_i *) }} void. . . main(void) { }. . . OSTask. Create. Periodic(f void main(void) { i , Ti , φ. . . i, s, i); OSTask. Create. Periodic(fi, Ti, . . . } φi, s, i); . . . }

Periodic task implementation OS_EVENT* Task 1 Sem; void Task(void (*f)(void)) {. . . INT

Periodic task implementation OS_EVENT* Task 1 Sem; void Task(void (*f)(void)) {. . . INT 8 U err; while (true) { OSTask. Wait. Period(); OSSem. Pend(Task 1 Sem, 0, &err); f(); } } void OSTime. Tick(void) {. . . if (* Task_i period expired *) *) {{ Task 1 period (* signal Task_i *) OSSem. Post(Task 1 Sem); }. . . } void main(void) {. . . OSTask. Create. Periodic(f Task 1 Sem = OSSem. Create(0); i , Ti , . . . φi, s, i); }. . . } • Synchronize loop iterations using semaphores Mike Holenderski, m. [email protected] nl 49

Summary of mutual exclusion primitives Primitive Pros Cons Disable interrupts • Avoid deadlock •

Summary of mutual exclusion primitives Primitive Pros Cons Disable interrupts • Avoid deadlock • Simplementation • Prevent interference from interrupts • Higher priority tasks not sharing resources are penalized • Interrupts can be missed Disable scheduler • Avoid deadlock • Simplementation • Allow interrupts • Higher priority tasks not sharing resources are penalized • Cannot guard resources shared with ISRs Mutex • Allow interrupts • Higher priority tasks not sharing resources are not penalized • Avoid “unbounded” priority inversion • Can lead to deadlock (depends on implementation) • Cannot guard resources shared with ISRs • Suspension not allowed in ISRs Semaphore • Allow interrupts • Higher priority tasks not sharing resources are not penalized Mike Holenderski, m. [email protected] nl 50 • • Can lead to deadlock Cannot guard resources shared with ISRs Suspension not allowed in ISRs “Unbounded” priority inversion

References • Recommended reading: – [Burns] Ch. 5. 1 -5. 4, 11. 8, 11.

References • Recommended reading: – [Burns] Ch. 5. 1 -5. 4, 11. 8, 11. 9 – Mike Jones, “What really happened on Mars? ”, 1997 • http: //research. microsoft. com/~mbj/mars_pathfinder/ mars_pathfinder. html – T. Baker, “Stack-based scheduling for realtime processes”, Journal of Real-Time Systems, vol 3, 1991 Mike Holenderski, m. [email protected] nl 51