Planche 1
Concurrency 1
Shared Memory
Jean-Jacques Lévy
jeanjacqueslevy.net/dea

 Planche 2

## Why concurrency?

1. Programs for multi-processors
2. Drivers for slow devices
3. Human users are concurrent
4. Distributed systems with multiple clients
5. Reduce lattency
6. Increase efficiency, but Amdahl's law
S=
N
b*N + (1-b)
(S = speedup, b = sequential part, N processors)

 Planche 3

## Implicit Communication

Suppose x is a global variable. At beginning, x=0

Consider
S = [x := x+1; x := x+1 |
| x:= 2*x]

T = [x := x+1; x := x+1 |
|  wait (x=1); x := 2*x]
After S, then x Î {2,3,4}
After T, then x Î {3,4}
T may be blocked

Conclusion

In S and T, interaction via x (shared memory)

 Planche 4

## Atomicity

Suppose x is a global variable. At beginning, x=0

Consider
S = [x := x+1 |
| x := x+1]

After S, then x=2.

However if
[x := x+1] compiled into [A := x+1; x := A]

Then
S = [A := x+1; x := A] |
| [B := x+1; x := B]

After S, then x Î {1,2}.

Conclusion
1. [x := x+1] was firstly considered atomic
2. Atomicity is important
 Planche 5

## Critical section -- Mutual exclusion

Let P0 = [···; C0; ···] and P1 = [···; C1; ···]

C
0 and C1 are critical sections (ie should not be executed simultaneously).

Solution 1 At beginning, turn = 0.
 P0 : ···   while turn != 0 do     ;   C0;   turn := 1;   ··· P1 : ···   while turn != 1 do     ;   C1;   turn := 0;   ···

P
0 privileged, unfair.

 Planche 6

## Critical section -- Mutual exclusion

Solution 2 At beginning, a0 = a1 = false .
 P0 : ···   while a1 do     ;   a0 := true;   C0;   a0 := false;   ··· P1 : ···   while a0 do     ;   a1 := true;   C1;   a1 := false;   ···

False.

Solution 3 At beginning, a
0 = a1 = false .
 P0 : ···   a0 := true;   while a1 do     ;   C0;   a0 := false;   ··· P1 : ···   a1 := true;   while a0 do     ;   C1;   a1 := false;   ···

Deadlock. Both P0 and P1 blocked.
 Planche 7

## Dekker's Algorithm (CACM 1965)

At beginning, a0 = a1 = false , turnÎ{0,1}
 P0 : ···   a0 := true;   while a1 do     if (turn != 0)  {       a0 := false;       while (turn != 0)         ;       a0 := true;     }   C0;   turn := 1; a0 := false;   ··· P1 : ···   a1 := true;   while a0 do     if (turn != 1)  {       a1 := false;       while (turn != 1)         ;       a1 := true;     }   C1;   turn := 0; a1 := false;   ···

 Planche 8

## Peterson's Algorithm (IPL June 81)

At beginning, a0 = a1 = false , turnÎ{0,1}
 P0 : ···   a0 := true;   turn := 1;   while a1 && turn != 0 do     ;   C0;   a0 := false;   ··· P1 : ···   a1 := true;   turn := 0;   while a0 && turn != 1 do     ;   C1;   a0 := false;   ···

 Planche 9

## Synchronization

Concurrent/Distributed algorithms
1. Lamport: barber, baker, ...
2. Dekker's algorithm for P0, P1, PN (Dijsktra 1968)
3. Peterson is simpler and can be generalised to N processes
4. Proofs ? By model checking ? With assertions ? In temporal logic (eg Lamport's TLA)?
5. Dekker's algorithm is too complex
6. Dekker's algorithm uses busy waiting
7. Fairness acheived because of fair scheduling
Need for higher constructs in concurrent programming.

Exercice 1 Try to define fairness.

 Planche 10

## Semaphores

A generalised semaphore s is integer variable with 2 operations

wait(s): If s > 0 then s := s-1
Otherwise be suspended on s.

signal(s): If some process is suspended on s, wake it up
Otherwise s := s+1.

Now mutual exclusion is easy:
At beginning, s = 1.
Then P
1 || P2 where
P
1 = [···; wait(s) ;  A;   signal(s); ···]
P
2 = [···; wait(s) ;  B;   signal(s); ···]
 Planche 11

## Operational (micro-)semantics (sequential part)

Language
 P,Q ::= skip  | x := e |  if  b  then  P  else  Q | P;Q | while  b  do  P e ::= expression

Semantics (SOS)
á skip ,  s ñ ® á ·s ñ á x := es ñ ® á ·s[s(e)/x] ñ
s(e) = true
á  if  e  then  P  else  Qs ñ ® á Ps ñ
s(e) = false
á  if  e  then  P  else  Qs ñ ® á Qs ñ
á Ps ñ ® á P',  s' ñ
á P;Qs ñ ® á P';Qs' ñ
(P' ¹ ·)
á Ps ñ ® á ·s' ñ
á P;Qs ñ ® á Qs' ñ
s(e) = true
á while  e  do  Ps ñ ® á P;while  e  do  Ps ñ
s(e) = false
á while  e  do  Ps ñ ® á ·s ñ

s Î Variables |
® Values s[v/x](x) = v s[v/x](y) = s(y) if y ¹ x
 Planche 12

## Operational semantics (parallel part)

Language
P,Q ::= ... | P || Q |  wait  b | await  b  do  P

Semantics (SOS)
á Ps ñ ® á P',  s' ñ
á P || Qs ñ ® á P' || Qs' ñ
á Qs ñ ® á Q',  s' ñ
á P || Qs ñ ® á P || Q',  s' ñ
á · || ·s ñ ® á ·s ñ
s(b) = true
á  wait  bs ñ ® á ·s ñ
s(b) = true  á Ps ñ ® á P',  s' ñ
á await  b  do  Ps ñ ® á P',  s' ñ
s(b) = true  á Ps ñ ® á ·s' ñ
á await  b  do  Ps ñ ® á ·s' ñ

Exercice 2 Complete SOS for e and v
Exercice 3 Find SOS for boolean semaphores.
Exercice 4 Avoid spurious silent steps in  if , while  and |
|.
 Planche 13

## SOS reductions

Notations
á P0s0 ñ ® á P1s1 ñ ® á P2s2 ñ ® ··· á Pnsn ñ ®

We write
 á P0,  s0 ñ ®* á Pn,  sn ñ when n ³ 0, á P0,  s0 ñ ®+ á Pn,  sn ñ when n > 0.

Remark that in our system, we have no rule such as
s(b) = false
á  wait  bs ñ ® á  wait  bs ñ

Ie no busy waiting. Reductions may block. (Same remark for await  b  do  P).
 Planche 14

## Atomic statements (Exercices)

Exercice 5 If we make following extension
P,Q ::= ... | { P }
what is the meaning of following rule?
á Ps ñ ®+ á ·s' ñ
á {P},  s ñ ® á ·s' ñ

Exercice 6 Show await  b  do  P ºwait  b; P }

Exercice 7 Meaning of {while  true   do  skip } ? Find simpler equivalent statement.

Exercice 8 Try to add procedure calls to our SOS semantics.

 Planche 15

## Producer - Consumer

 Planche 16

## A typical thread package. Modula-3

```

TYPE
T <: ROOT;
Mutex = MUTEX;
Condition <: ROOT;
```
A Thread.T is a handle on a thread. A Mutex is locked by some thread, or unlocked. A Condition is a set of waiting threads. A newly-allocated Mutex is unlocked; a newly-allocated Condition is empty. It is a checked runtime error to pass the NIL Mutex, Condition, or T to any procedure in this interface.
 Planche 17
```
PROCEDURE Wait(m: Mutex; c: Condition);
```
The calling thread must have m locked. Atomically unlocks m and waits on c. Then relocks m and returns.
```
PROCEDURE Acquire(m: Mutex);
```
Wait until m is unlocked and then lock it.
```
PROCEDURE Release(m: Mutex);
```
The calling thread must have m locked. Unlocks m.
```
```
All threads waiting on c become eligible to run.
```
PROCEDURE Signal(c: Condition);
```
One or more threads waiting on c become eligible to run.
 Planche 18

## Locks

A LOCK statement has the form:
```
LOCK mu DO S END
```
where S is a statement and mu is an expression. It is equivalent to:
```
WITH m = mu DO
END
```
where m stands for a variable that does not occur in S.

 Planche 19

## Try Finally

A statement of the form:
```
TRY S_1 FINALLY S_2 END
```
executes statement S1 and then statement S2. If the outcome of S1 is normal, the TRY statement is equivalent to S1;S2. If the outcome of S1 is an exception and the outcome of S2 is normal, the exception from S1 is re-raised after S2 is executed. If both outcomes are exceptions, the outcome of the TRY is the exception from S2.

 Planche 20

## Concurrent stack

Popping in a stack:
```

LOCK m DO
END;
```
Pushing into a stack:
```
LOCK m DO
END;
```
Caution: `WHILE` is safer than `IF` in Pop.

 Planche 21

## Concurrent table

```
VAR table := ARRAY [0..999] of REFANY {NIL, ...};
VAR i:[0..1000] := 0;

PROCEDURE Insert (r: REFANY) =
BEGIN
IF r <> NIL THEN

table[i] := r;
i := i+1;

END;
END Insert;
```
Exercice 9 Complete previous program to avoid lost values.

 Planche 22

2
Thread A trying to lock m
2
Thread B trying to lock m
1

Simple stragegy for semaphore controls

Respect a partial order between semaphores. For example, A and B uses m
1 and m2 in same order.

 Planche 23

## Exercices

Exercice 10 Simulate conditions with semaphores. Hint: count number of waiting processes on condition.

Exercice 11 Readers and writers. A buffer may be read by several processes at same time. But only one process may write in it. Write procedures StartRead, EndRead, StartWrite, EndWrite.

Exercice 12 Give SOS for operations on conditions.

This document was translated from LATEX by HEVEA.