Locks and Semaphores Ch4
Locks and Semaphores Ch4
entry () {
Locks and Semaphores bool spin = true;
Swap(spin, s);
while (spin)
Swap(spin, s);
}
exit() {
Some slides and/or pictures are adapted from
s = false;
• Operating System Concepts, 9th edition, by Silberschatz, Galvin, }
Gagne, John Wiley & Sons, 2013
• Lecture notes by Dr. Prof. John Kubiatowicz (Berkeley)
1 2
1 2
3 4
Naïve use of Interrupt Enable/Disable: Problems Better Implementation of Locks by Disabling Interrupts
Key idea: maintain a lock variable and impose mutual exclusion only
during operations on that variable
Can’t let user do this! Consider following:
LockAcquire();
While(TRUE) {;} int value = FREE;
5 6
1
2/28/2019
7 8
9 10
11 12
2
2/28/2019
13 14
15 16
Acquire() { Release() {
• Synchronization tool that does not require
disable interrupts; disable interrupts; busy waiting.
if (value == BUSY) { if (anyone on wait queue) {
put thread on wait queue; take thread off wait queue • Semaphore is an object contains a
Place on ready queue;
Go to sleep();
// Enable interrupts? } else { (private) integer value and 2 operations.
value = FREE;
} else {
} – P operation, also called Down or Wait
value = BUSY;
}
enable interrupts; • Acquire a resource
}
enable interrupts; – V operation, also called Up or Signal
}
• Release a resource
Basically replace • Semaphores are “resource counters”.
– disable interrupts while (test&set(guard));
– enable interrupts guard = 0;
18
17 18
3
2/28/2019
Semaphore Implementation
• Semaphore from railway analogy
– Here is a semaphore initialized to 2 for • Define a semaphore as a record
resource control: typedef struct {
int value;
struct process *L;
} semaphore;
19 20
21 22
Semaphore as a General
Bounded Buffer Problem
Synchronization Tool
• Execute B in Pj only after A executed in Pi • There is one Buffer object used to pass objects
from producers to consumers. The problem is
• Use semaphore flag initialized to 0
to allow concurrent access to the Buffer by
• Code: producers and consumers, while ensuring that
Pi Pj – Consumer must wait for producer to fill
buffers, if none full (scheduling constraint)
– Producer must wait for consumer to empty
A wait(flag) buffers, if all full (scheduling constraint)
– Only one thread can manipulate buffer queue
signal(flag) B at a time (mutual exclusion)
23 24
23 24
4
2/28/2019
char buf[n], int front = 0, rear = 0; char buf[n], int front = 0, rear = 0;
semaphore empty = n, full = 0; semaphore empty = n, full = 0, mutex = 1;
Producer() Consumer ()
Producer() Consumer () while (1) { while (1) {
while (1) { while (1) { produce message m; wait(full);
produce message m; wait(full); wait(empty); wait(mutex);
wait(empty); m = buf[front]; wait(mutex); m = buf[front];
buf[rear] = m; front = front “+” 1; buf[rear] = m; front = front “+” 1;
rear = rear “+”1; signal(empty); rear = rear “+”1; signal(mutex);
signal(full); consume m; signal(mutex); signal(empty);
} } signal(full) consume m;
} }
25 26
25 26
27 28
27 28
• Reader Process
Readers-Writers Problem readEnter () {
Semaphore Solution wait(mutex);
readcount++;
• Shared data if (readcount == 1)
wait(wrt);
semaphore mutex = 1, wrt = 1; signal(mutex);
int readcount = 0;
}
• Writer Process readExit() {
writeEnter () {
wait(wrt); wait(mutex);
} readcount--;
if (readcount == 0)
writeExit () { signal(wrt);
signal(wrt); signal(mutex);
} }
29 30
29 30
5
2/28/2019
31 32
33 34