Today’s topic:
Resource/Data Sharing and Synchronization
Priority Ceiling Protocols
Two classic papers on real-time systems
L. Sha, R. Rajkumar, and J. P. Lehoczky, Priority Inheritance
Protocols: An Approach to Real-Time Synchronization. In IEEE
Transactions on Computers, vol. 39, pp. 1175-1185, Sep. 1990.
C. L. Liu , James W. Layland, Scheduling Algorithms for
Multiprogramming in a Hard-Real-Time Environment, Journal of the
ACM (JACM), v.20 n.1, p.46-61, Jan. 1973
1
Basic functions of RTOS kernel
Time management
Task mangement
Interrupt handling
Memory management
no virtual memory for hard RT tasks
Exception handling
Task synchronization
Avoid priority inversion
Task scheduling
The simpliest form of priority inversion
Task 1 Task 9
- Shared Resource R -
- -
P(S) P(S)
Using R Using R
V(S) V(S)
- -
- -
Task 1 P(S)
computing
using R
Task 9 P(S) V(S)
blocked
2
Un-bounded priority inversion
Task 1 Task 9 Task 2
-
- Shared Resource R -
- - -
P(S) P(S) -
Using R Using R -
V(S) V(S)
- -
- -
Task 1 P(S) ... V(S)
Task 2 ...
computing
using R
Task 9 P(S) V(S)
blocked
Solutions
Tasks are ’forced’ to follow pre-defined rules when
requesting and releasing resources (locking and
unlocking semaphores)
The rules are called ’Resource access protocols’
NPP, BIP, HLP, PCP
3
Non Preemption Protocol (NPP)
Modify P(S) so that the ”caller” is assigned
the highest priority if it succeeds in locking S
Highest priority=non preemtion!
Modify V(S) so that the ”caller” is assigned its own
priority back when it releases S
This is the simplest method to avoid Priority Inversion!
NPP: + and –
Simple and easy to implement (+), how?
Deadlock free (++)
Number of blockings = 1 (+)
Allow low-priority tasks to block high-priority tasks
including those that have no sharing resources (-)
Missinig all deadlines!
P(s) V(s)
4
Basic Priority Inheritance Protocol (BIP)
supported in RT POSIX
Idea:
A gets semaphore S
B with higher priority tries to lock S, and blocked by S
B transfers its priority to A (so A is resumed and run with
B’s priority)
Run time behaviour: whenever a lower-
priotity task blocks a higher priority task, it
inherits the priority of the blocked task
Example
V(S1)
P(S1) P(S2) V(S2)
H Task 1
P(S1)
V(S1)
M Task 2
P(S2)
V(S2)
L Task 3
Blocked
Using S1
Running with priority H Using S2
10
5
Problem 1: potential deadlock
P(S2)
H P(S1) Task 1
P(S1)
L P(S2) Deadlock! Task 2
Task 2: ... P(S2) ... P(S1)...
Task 1: ... P(S1) ... P(S2)...
11
Problem 2: chained blocking – many preemptions
V(S1)
P(S1) P(S2) V(S2)
H Task 1
P(S1)
V(S1)
M Task 2
P(S2)
V(S2)
L Task 3
Blocked
Using S1
Using S2
Task 1 needs M resources may be blocked M times:
many preemptions/run-time overheads
12
maximal blocking=sum of all CS sections for lower-priority tasks
6
BIP: Blocking time calculation
Let
CS(k,S) denote the computing time for the critical section
that task k uses semaphore S.
The maximal blocking time for task i:
B= {CS(k,S)| task i, k share S and pri(k)<pri(i)<=C(S)}
This is not quite true e.g. when there is a deadlock!
13
Properties of BIP: + and -
Bounded Priority inversion (+)
Reasonable Run-time performance (+)
Potential deadlocks (-)
Chain-blocking – many preemptions (-)
14
7
Implementation of Ceiling Protocols
Main ideas:
Priority-based scheduling
Implement P/V operations on Semaphores to assign task
priorities dynamically
15
Semaphore Control Block for BIP
counter
queue
Pointer to next SCB
Holder
16
8
Standard P-operation (without BIP)
P(scb):
Disable-interrupt;
If scb.counter>0 then {scb.counter - -1;
else
{save-context( );
current-task.state := blocked;
insert(current-task, scb.queue);
dispatch();
load-context() }
Enable-interrupt
17
P-operation with BIP
P(scb):
Disable-interrupt;
If scb.counter>0 then {scb.counter - -1;
scb.holder:= current-task
add(current-task.sem-list,scb)}
else
{save-context( );
current-task.state := blocked;
insert(current-task, scb.queue);
/* queue sorted according to task priority */
save(scb.holder.priotiry);
scb.holder.priority := current-task.priority;
dispatch();
load-context() }
Enable-interrupt
18
9
Standard V-operation (without BIP)
V(scb):
Disable-interrupt;
If not-empty(scb.queue) then
{ next-to-run := get-first(scb.queue);
next-to-run.state := ready;
insert(next-to-run, ready-queue);
save-context();
schedule(); /* dispatch invoked*/
load-context() }
else scb.counter ++1;
Enable-interrupt
19
V-operation with BIP
V(scb):
Disable-interrupt;
current-task.priority := ”original/previous priority”
/* restore the previous priority of the ”caller” i.e current-tast*/
If not-empty(scb.queue) then
{ next-to-run := get-first(scb.queue);
/*queue sorted according to task priority */
next-to-run.state := ready;
scb.holder := next-to-run;
add(next-to-run.sem-list, scb);
insert(next-to-run, ready-queue);
save-context();
schedule(); /* dispatch invoked*/
load-context() }
else scb.counter ++1;
Enable-interrupt
20
10
Immediate Priority Inheritance:
=Highest Locker’s Priority Protocol (HLP)
=Priority Protect Protocol (PPP)
Adopted in Ada95 (protected object), POSIX mutexes
Idea: define the ceiling C(S) of a semaphore S to be
the highest priority of all tasks that use S during
execution. Note that C(S) can be calculated statically
(off-line).
21
Run-time behaviour of HLP
Whenever a task succeeds in holding a semaphor S,
its priority is changed dynamically to the maximum of
its current priority and C(S).
When it finishes with S, it sets its priority back to
what it was before
22
11
Example
priority use C(S1)=M
Task 1 H S3 C(S2)=L
C(S3)=H
Task 2 M S1, S
C(S)=M
Task 3 L S1, S2
Task 4 Lower S2, S
23
Example: Highest Locker’s Priority Protocol
M and Lower share S
computing
H Task 1 blocked
New release of Task 2 using resource
M Task 2
P(S) V(S)
L
P(S) V(S)
Task 3
Lower
24
12
Property 1: Deadlock free (HLP)
P(S2) P(S1)
released
H Task 1
P(S1) P(S2)
L Task 2
Once task 2 gets S1, it runs with pri H, task 1 will
be blocked (no chance to get S2 before task 2)
25
Property 2:
Tasks will be blocked at most once
P(S1) V(S1)V(S2)
P(S2)
Ready and blocked
Ready and blocked P(S2) V(S2)
P(S1) V(S1)
26
13
HLP: Blocking time calculation
Let
CS(k,S) denote the computing time for the critical section
that task k uses semaphore S.
Then the maximal blocking time B for task i is as
follows:
B=max{CS(k,S)| task i,k share S, pri(k)<pri(i)<=C(S)}
27
Implementation of HLP
Calculate the ceiling for all semaphores
Modify SCB
Modify P and V-operations
28
14
Semaphore Control Block for HLP
counter
queue
Pointer to next SCB
Ceiling
29
P-operation with HLP
P(scb):
Disable-interrupt;
If scb.counter>0 then
{ scb.counter - -1;
save(current-task.priority);
current-task.priority := Ceiling(scb) }
else
{save-context();
current-task.state := blocked
insert(current-task, scb.queue);
dispatch();
load-context() }
Enable-interrupt
30
15
V-operation with HLP
V(scb):
Disable-interrupt;
current-task.priority := get(previous-priority)
If not-empty(scb.queue) then
next-to-run := get-first(scb.queue);
next-to-run.state := ready;
next-to-run.priority := Ceiling(scb);
insert(next-to-run, ready-queue);
save-context();
schedule(); /* dispatch invoked*/
load-context();
end then
else scb.counter ++1;
end else
Enable-interrupt
31
Properties of HLP: + and -
Bounded priority inversion
Deadlock free (+), Why?
Number of blocking = 1 (+), Why?
HLP is a simplified version of PCP (+)
The extreme case of HLP=NPP (-)
E.g when the highest priority task uses all semaphores, the
lower priority tasks will inherit the highest priority
32
16
Summary
NPP BIP HLP
Bounded Priority Inversion yes yes yes
Avoid deadlock yes no yes
Avoid Un-necessary blocking no yes yes/no
Blocking time calculalation Easy hard easy
33
Priority Ceiling Protocol (combining HLP and BIP)
Each semaphore S has a Ceiling C(S)
Run-time behaviour:
Assume that S is the semaphore with highest ceiling locked by
other tasks currently: C(S) is ”the current system ceiling”
If A wants to lock a semaphore (not necessarily S), it must have a
strictly higher priority than C(S) i.e. P(A) > C(S). Otherwise A is
blocked, and it transmitts its priority(+) to the task currently
holding S
34
17
Example: PCP
A: ...P(S1)...V(S1)... Prio(A)=H
B: ...P(S2)...P(S3)...V(S3)...V(S2)... Prio(B)=M C(S1)=H
C: ...P(S3)...P(S2)...V(S2)...V(S3) Prio(C)=L C(S2)=C(S3)=M
P(S1) V(S1)
Get S2 P(S3) V(S3)V(S2)
B arrives P(S2) Blocked on S3
P(S2) V(S2) V(S3)
P(S3)
Run with its own priority
Run with priority ”M+”
35
PCP: Blocking time calculation
Let
CS(k,S) denote the computing time for the critical section
that task k uses semaphore S.
The maximal blocking time for task i:
B = max{CS(k,S)| task i,k share S, pri(k)<pri(i)<=C(S)}
(which is the same as HLP)
36
18
Exercise: implementation of PCP
Implement P,V-operations that follow PCP
(this is not so easy)
37
Properties of PCP: + and -
Bounded priority inversion (+)
Deadlock free (+)
Number of blocking = 1 (+)
Better response times for high priority tasks (+)
Avoid un-necessary blocking
Not easy to implement (-)
38
19
Summary
NPP BIP HLP PCP
Bounded Priority Inversion yes yes yes yes
Deadlock free yes no yes yes
Un-necessary blocking yes no yes/no no
Blocking time calculalation easy hard easy easy
Number of blocking 1 >1 1 1
Implementation easy easy easy hard
39
20