Synchronization: semaphores and some more stuff 1 Operating Systems, 2014, Meni Adler, Danny Hendler...
-
Upload
dana-glenn -
Category
Documents
-
view
222 -
download
0
description
Transcript of Synchronization: semaphores and some more stuff 1 Operating Systems, 2014, Meni Adler, Danny Hendler...
Synchronization: semaphoresSynchronization: semaphoresand some more stuffand some more stuff
1Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
What's wrong with busy waiting?What's wrong with busy waiting?
Doesn't make sense for uni-processoro May cause priority inversion and deadlock
Wastes CPU timeo But is efficient if waiting-time is short
The mutual exclusion algorithms we saw used busy-waiting. What’s wrong with that?
2Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
What's wrong with busy waiting? What's wrong with busy waiting?
Busy waiting may cause priority-inversion and deadlockBusy waiting may cause priority-inversion and deadlock
Process A's priority is higher than process B's Process B enters the CS Process A needs to enter the CS, busy-waits for B to exit the CS Process B cannot execute as long as the higher-priority process A is executing/ready
Priority inversion and deadlock resultPriority inversion and deadlock result3Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
OutlineOutline
Semaphores and the producer/consumer problem Counting semaphores from binary semaphores Event counters and message passing synchronization
4Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Semaphores
up(S) [the `v’ operation] If there are blocked
processes, wake-up one of them
Else S++
down(S) [the ‘p’ operation] If S≤0 the process is blocked.
It will resume execution only after it is woken-up
Else S--
Two atomic operations are supported by a semaphore S:
S is non-negative
Supported by Windows, Unix, …
5Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Semaphores: is the following correct?
up(S) [the `v’ operation] S++ If there are blocked
processes, wake-up one of them
down(S) [the ‘p’ operation] If S≤0 the process is blocked.
It will resume execution only after it is woken-up
S--
Two atomic operations are supported by a semaphore S:
6Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
7
Consider the following bad scneario:Consider the following bad scneario:
S=0 and process A performs down(S) down(S) – A is blocked Process B performs up(S)up(S) – S=1 S=1 A is ready Process C performs down(S) down(S) – S=0 & C proceedsS=0 & C proceeds Process A gets a time-slice and proceeds – S=0 S=0
A single up() freed 2 down()sA single up() freed 2 down()sOperating Systems, 2011, Danny Hendler & Amnon Meisels
Pseudo-code in previous slide is wrong
Implementing mutex with semaphores
Shared data: semaphore lock; /* initially lock = 1 */
down(lock)
Critical section
up(lock)
Does the algorithm satisfy mutex?Does it satisfy deadlock-freedom?Does it satisfy starvation-freedom?
YesYesDepends…
8Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Semaphore as a General Synchronization ToolSemaphore as a General Synchronization Tool
Execute B in Pj only after A executed in Pi
Use semaphore flag initialized to 0 Code:
Pi Pj
… …A down(flag)
up(flag) B
Execute B in Pj only after A executed in Pi
Use semaphore flag initialized to 0 Code:
Pi Pj
… …A down(flag)
up(flag) B
0
time
9Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
More on synchronization using semaphoresMore on synchronization using semaphores
Three processes p1; p2; p3
semaphores s1 = 1, s2 = 0;p1p1 p2p2 p3p3down(s1s1); down(s2s2); down(s2s2);A B Cup(s2s2); up(s2s2); up(s1s1);
Which execution orders of A, B, C, are possible?
(A B* C)*10Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
P0 P1
down(S); down(Q); down(Q); down(S);
move1 move2up(S); up(Q);up(Q) up(S);
1
1
Example: move money between two accounts which are protected by semaphores S and Q
No guarantee for correct synchronization No guarantee for correct synchronization
Does this work?Deadlock!
11Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Negative-valued semaphoresNegative-valued semaphores
up(S) S++ If there are blocked
processes (i.e. S≤0), wake-up one of them
-3
down(S) S-- If S<0 the process is blocked.
It will resume execution only when S is non-negative
Two atomic operations are supported by a semaphore S:
If S is negative, then there are –S blocked If S is negative, then there are –S blocked processesprocesses
12Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
type semaphore = recordvalue: integer; L: list of process;
end;
Negative semaphore ImplementationNegative semaphore Implementation
-3
atomic down(S):S.value--;if (S.value < 0) { add this process to S.L; sleep; }
atomic up(S): S.value++;if (S.value <= 0) { remove a process P from S.L; wakeup(P); }
13Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
L
Implementing a spin-lock with TSLImplementing a spin-lock with TSL
In user space, one can use TSL (test-set-lock)mutex_lock:mutex_lock:
TSL REG, mutexCMP REG, #0JZE okokCALL thread_yieldthread_yield
JMP mutex_lockok:ok:
RET
mutex_unlock:mutex_unlock:MOV mutex, #0RET
14Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
type semaphore = recordvalue, flag: integer; L: list of process;
end;
-3
down(S):repeat until test-and-set(S.flag) S.value--; if (S.value < 0) { add this process to S.L; S.flag=0 sleep; } else S.flag=0
Implementing a negative semaphore with TSLImplementing a negative semaphore with TSL
up(S):repeat until test-and-set(S.flag) S.value++; if (S.value <= 0) { remove a process P from S.L; wakeup(P); }
S.flag=0
15Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
L
Any problem with this code?In down(), resetting flag and sleeping should be atomic.
More on semaphore implementationMore on semaphore implementation On a uni-processor, disabling interrupts may be used
TSL implementation works for multi-processors
On a multi-processor, we can use spin-lock mutual exclusion to protect semaphore access
Why is this better than busy-waiting in the 1st place?
Busy-waiting is now guaranteed to be very short
16Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Producer-Consumer Problem
Paradigm for cooperating processes, • producer process produces
information that is consumed by a consumer process
Two versions• unbounded-buffer places no
practical limit on the size of the buffer
• bounded-buffer assumes that there is a fixed buffer size
buff
er
in
out
17Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
2
6
Out
In
item1
item4
item3
item2
consumer
0buffer
producer
Bounded Buffer
1
2
3
4
5
7
18Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Implementation using semaphoresImplementation using semaphores
Two processes or more use a shared buffer in memory
The buffer has finite size(i.e., it is boundedbounded)
The producer writes to the buffer and the consumer reads from it
A full bufferfull buffer stops the producer
An empty bufferempty buffer stops the consumer
19Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Producer-ConsumerProducer-Consumer implementation with semaphores#define N 100 /* Buffer size */typedef int semaphoresemaphore;semaphoresemaphore mutex = 1; /* access control to critical section */semaphoresemaphore empty = N; /* counts empty buffer slots */semaphoresemaphore full = 0; /* counts full slots */
void producer(void) {int item;while(TRUE) {produce_item(&item); /* generate something... */downdown(&empty); /* decrement count of empty */downdown(&mutex); /* enter critical section */enter_item(item); /* insert into buffer */upup(&mutex); /* leave critical section */upup(&full); /* increment count of full slots */} }
20Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
void consumerconsumer(void){
int item;
while(TRUE) { downdown(&full); /* decrement count of full */ downdown(&mutex); /* enter critical section */ remove_item(&item); /* take item from buffer) */ upup(&mutex); /* leave critical section */ upup(&empty); /* update count of empty */ consume_item(item); /* do something... */
}}
21Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Producer-ConsumerProducer-Consumer implementation with semaphores
Outline
Semaphores and the producer/consumer problem Counting semaphores from binary semaphores Event counters and message passing synchronization
22Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
23Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Assumes only values 0 or 1
Wait blocks if semaphore=0
Signal (up operation) either wakes up a waiting process, if there is one, or sets value to 1 (if value is already 1, signal is “wasted”)
How can we implement a counting semaphore by using binary semaphores?
Binary SemaphoreBinary Semaphore
Implementing a counting semaphore with binary Implementing a counting semaphore with binary semaphores (user space): semaphores (user space): take 1take 1
down(S):down(S):down(S1);SS.value--;if(SS.value < 0){
up(S1); down(S2); }
else up(S1);
binary-semaphore S1 initially 1, S2 initially 0, S.value initially 1
up(S):up(S):down(S1);SS.value++;if(SS.value ≤ 0)
up(S2); up(S1)
This code does not work. Why?
24Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
L1:L2:
Race condition for counting semaphore Race condition for counting semaphore take 1take 1
1. Processes Q1 – Q4 perform down(S), Q2 – Q4 are preempted between lines
L1 and L2: the value of the counting semaphore is now -3
2. Processes Q5-Q7 now perform up(S): the value of the counting semaphore is
now 0
3. Now, Q2-Q4 wake-up in turn and perform line L2 (down S2)
4. Q2 runs but Q3-Q4 block.
25Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
There is a discrepancy between the value of S and the There is a discrepancy between the value of S and the number of processes waiting on itnumber of processes waiting on it
Implementing a counting semaphore with binary Implementing a counting semaphore with binary semaphores (user space): semaphores (user space): take 2take 2
down(S):down(S):down(S1);SS.value--;if(SS.value < 0){up(S1); //L1down(S2); } //L2up(S1);
up(S):up(S):down(S1);SS.value++;if(SS.value ≤ 0)
up(S2); else up(S1)
Does this code work?
26Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
binary-semaphore S1 initially 1, S2 initially 0, S.value initially 1
up(S1) is performed by up(S) only if no process waits on S2only if no process waits on S2 Q5 leaves up(S) without releasing S1
Q6 cannot enter the critical section that protects the counter
It can only do so after one of Q2-Q4 releases S1
This generates a “lock-step” situation: an up(), a down(), an up()…
The critical section that protects the counter is entered The critical section that protects the counter is entered
alternately by a producer or a consumeralternately by a producer or a consumer
The effect of the added ‘else’The effect of the added ‘else’
27Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Recall the bounded-buffer algorithmRecall the bounded-buffer algorithm#define N 100typedef int semaphoresemaphore;semaphoresemaphore mutex = 1;semaphoresemaphore empty = N;semaphoresemaphore full = 0;void producerproducer(void) {
int item;while(TRUE) {produce_item(&item);downdown(&empty);downdown(&mutex);enter_item(item);upup(&mutex);upup(&full);} }
void consumerconsumer(void){
intitem;
while(TRUE) { downdown(&full); downdown(&mutex); remove_item(&item); upup(&mutex); upup(&empty); consume_item(item);
}}
28Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
Consider a Bounded buffer of 5 slots.Assume there are 6 processes each filling five slots in turn.
Empty.Value = 521
3 4
5 6
29Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
1. 1. five slots are filled by the first producer
Empty.Value = 021
3 4
5 6
30Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario1. 1. The second producer is blocked
Empty.Value = -121
3 4
5 6
31Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
1. 1. The third producer is blocked
Empty.Value = -221
3 4
5 6
32Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
11. The fourth producer is blocked
Empty.Value = -321
3 4
5 6
33Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
1. 1. The fifth producer is blocked
Empty.Value = -421
3 4
5 6
34Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
2. 2. All blocked producers are waiting on S2
Empty.Value = -521
3 4
5 6
35Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
3. 3. The consumer consumes an item and is blocked on Empty.S1 until a producer adds an item.
Empty.Value = -521
3 4
5 6
36Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
3. 3. The consumer consumes an item and is blocked on S1 , one producer adds an item.
Empty.Value = -421
3 4
5 6
37Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
44. Consumer must consume, only then another producer wakes up and produces an item
Empty.Value = -321
3 4
5 6
38Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
4. 4. Same as in step 3.
Empty.Value = -221
3 4
5 6
39Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
A Problematic Scheduling Scenario
5. 5. And again…
Empty.Value = -121
3 4
5 6
40Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Implementing a counting semaphore with binary Implementing a counting semaphore with binary semaphores (user space): semaphores (user space): take 3 take 3 (P.A. Kearns, 1988)(P.A. Kearns, 1988)
down(S)down(S)down(S1);SS.value--;if(SS.value < 0){
up(S1); //L1down(S2); //L2down(S1);SS.wake--; if(SS.wake > 0) then up(S2);} //L3
up(S1);
up(S):up(S):down(S1);SS.value++;if(SS.value <= 0) {
SS.wake++; up(S2); }up(S1);
binary-semaphore S1=1, S2=0, value initially 1, integer wake=0
Does THIS work?
41Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Correctness arguments (Kearns)…
The counter S.wakeS.wake is used when processes performing down(S)down(S) are preempted between lines L1 and L2
In such a case, up(S2) performed by processes during up(S)up(S) has no effect
However, these processes accumulate their waking signals on the (protected) counter S.wakeS.wake
After preemption is over, any single process that wakes up from its block on down(S2) checks the value of S.wakeS.wake
The check is again protected For each count of the wake-up signals, the awakened process
performs the up(S2) (in line L3) Each re-scheduled process wakes up the next oneEach re-scheduled process wakes up the next one
42Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Kearns' algorithm is wrongKearns' algorithm is wrong
Processes P0..P7 perform down(S),down(S), P0 goes through, P1..P7 are preempted just
after line L2 of the operation
Processes P8..P11 perform up(S)up(S) and their up(S2) operations release, say, P1..P4
Processes P5, P6, P7 are still waiting on S2 and S.wake = 4S.wake = 4
Processes P1..P4 are ready, just before line L3
Each of P1..P3 will decrement S.wakeS.wake in its turn, check that it's positive and
signal one of P5..P7
Four Four upup operations have released 7 operations have released 7 down down operations operations
43Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Implementing a counting semaphore with binary Implementing a counting semaphore with binary semaphores (user space): semaphores (user space): take 4 take 4 (Hemmendinger, 1989)(Hemmendinger, 1989)
down(S)down(S)down(S1);SS.value--;if(SS.value < 0){
up(S1);down(S2);down(S1);SS.wake--; if(SS.wake > 0) then up(S2);} // L3
up(S1);
up(S):up(S):down(S1);SS.value++;if(SS.value <= 0) {
SS.wake++; if (S.wake == 1) up(S2); }up(S1);
binary-semaphore S1=1, S2=0, integer wake=0
This works
44Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Implementing a counting semaphore with binary Implementing a counting semaphore with binary semaphores (user space): semaphores (user space): take 5take 5 (Barz, 1983)(Barz, 1983)
down(S)down(S)down(S2);down(S1);
S.value--; if (S.value>0) then up(S2); up(S1);
up(S):up(S):down(S1);S.value++;if(S.value == 1) {
up(S2); }up(S1);
binary-semaphore S1=1, S2=min(1, init_value), value=init_value
This works, is simpler, and was published earlier …(!)
Can we switch the order of downs in down(S)? 45Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Correctness arguments…Correctness arguments… The critical section is guarded by S1 and each of the operations
down(SS) and up(SS) uses it to correctly update the value of SS.value After updating (and inside the critical section) both operations
release the S2 semaphore only if value is positive SS.value is never negative, because any process performing
down(SS) is blocked at S2
Signals cannot be 'wasted' Signals cannot be 'wasted'
46Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Fairness of semaphores
Order of releasing blocked processes:o Weak – up() performing process enters after enters after (one of the)
blocked processeso Strong – An upper bound on the number of entries of
process that performed up() if others are waiting Unfair:Unfair:
o No guarantee about the number of times the up() performing process enters before the blocked
o Open competition each time the lock is freeo Imitating the Java 'wait' 'notify' mechanismo Or the spin-lock of XV6…
47Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Outline
Semaphores and the producer/consumer problem Counting semaphores from binary semaphores Event counters and message passing synchronization
48Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Event CountersEvent Counters Integer counters with three operations:
o Advance(E): increment E by 1, wake up relevant sleepers
o Await(E,v): wait until E ≥ v. Sleep if E < vSleep if E < v
o Read(E): return the current value of E
Counter value is ever increasingCounter value is ever increasing
The Read() operation is not required for the bounded-buffer implementation in the next slide
49Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
producer-consumer with Event Countersproducer-consumer with Event Counters(for a single producer and a single consumer)(for a single producer and a single consumer)
#define N 100typedef int event_counter;event_counter in = 0; /* counts inserted items */event_counter out = 0; /* items removed from buffer */
void producer(void){int item, sequence = 0;
while(TRUE) {produce_item(&item);sequence = sequence + 1; /* counts items produced */await(out, sequence - N); /* wait for room in buffer */enter_item(item); /* insert into buffer */advance(&in); /* inform consumer */
}}
50Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Event countersEvent counters (producer-consumer)
void consumer(void){ int item, sequence = 0;
while(TRUE) { sequence = sequence + 1; /* count items consumed */ await(in, sequence); /* wait for item */ remove_item(&item); /* take item from buffer */ advance(&out); /* inform producer */ consume_item(item);
}}
51Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
MessageMessage Passing Passing – no shared memory– no shared memory
In a multi-processor system without shared memory, synchronization can be implemented by message passing
Implementation issues:o Acknowledgements may be required (messages may be lost)o Message sequence numbers required to avoid message duplicationo Unique process addresses across CPUs (domains..)o Authentication (validate sender’s identity, a multi-machine environment…)
Two main functions:o send(destination, &message);o receive(source, &message) block while waiting...
52Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Producer-consumer with Message PassingMessage Passing
#define N 100#define MSIZE 4 /* message size */
typedef int message(MSIZE);void producer(void){
int item;message m; /* message buffer */
while(TRUE) {produce_item(&item);receive(consumer, &m); /*wait for an empty */construct_message(&m, item);send(consumer, &m); /* send item */
}}
53Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Message passingMessage passing (cont.) (cont.)
void consumer(void){int item, i;message m;
for(i = 0; i < N; i++) send(producer, &m); /* send N emptiesempties */
while(TRUE) {receive(producer, &m); /* get message with item */extract_item(&m, &item);send(producer, &m); /* send an empty reply */consume_item(item); }
}
54Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels
Message passing variationsMessage passing variations
Messages can be addressed to a process address or to a mailbox
o Mailboxes are generated with some capacity. When sending a message to a full
mailbox, a process blocks
o Buffer management done by mailbox
Unix pipes - a generalization of messages … no fixed size message (blocking
receive)
If no buffer is maintained by the system, then send and receive must run in
lock-step. Example: Unix rendezvous
55Operating Systems, 2014, Meni Adler, Danny Hendler & Amnon Meisels