Semaphores, bounded-buffer
Semaphores, bounded-buffer
Semaphores, bounded-buffer
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Oct 2, 2000<br />
• Processes and concurrent programming<br />
– Synchronization and communication<br />
– Higher-level primitives<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.28<br />
CS134a, 2000
Peterson’s algorithm<br />
• Use both turn and critical section flags<br />
bool c1 = true;<br />
bool c2 = true;<br />
int turn;<br />
cobegin<br />
while(true) {<br />
c1 = false;<br />
turn = 1;<br />
while(!c2 && turn = 1); // busy wait<br />
critical_section_1;<br />
c1 = true;<br />
program_1;<br />
} | ...<br />
coend<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.29<br />
CS134a, 2000
Multi-process mutual exclusion<br />
• n processes, numbered 0...n-1<br />
• Bakery algorithm: when entering the critical section<br />
– Take a number and wait<br />
– Can’t guarantee that numbers are distinct<br />
✴ Process with lowest process-id goes first<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.30<br />
CS134a, 2000
Bakery algorithm<br />
bool choosing[n]; // initially false<br />
int number[n]; // initially 0<br />
cobegin<br />
/* process i */<br />
while(true) {<br />
choosing[i] = true;<br />
number[i] = max(number[0], ..., number[n]) + 1;<br />
choosing[i] = false;<br />
for(j = 0; j != i; j++) {<br />
while(choosing[j]); // busy wait<br />
while(number[j] && number[j]
Problems with these algorithms<br />
• Solutions are complex and awkward<br />
• Too much time spent in the busy wait<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.32<br />
CS134a, 2000
<strong>Semaphores</strong> (Dijkstra 1965)<br />
• Slightly more abstract primitives<br />
• A semaphore is a non-negative integer variable with two<br />
atomic operations:<br />
– Passeren (wait): P(s) decrements s by 1 if possible,<br />
otherwise it waits until s becomes positive, then<br />
decrements it.<br />
– Verhogen (signal): V(s) increments s by one.<br />
• The operations are atomic: no other process is allowed to<br />
access the semaphore during a P or V operation, unless<br />
the P operation is blocked.<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.33<br />
CS134a, 2000
Mutual-exclusion with semaphores<br />
• Semaphore s;<br />
V(s); // increment the semaphore initially<br />
...<br />
P(s);<br />
critical section;<br />
V(s);<br />
...<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.34<br />
CS134a, 2000
The producer/consumer problem<br />
Producer<br />
Buffer<br />
Consumer<br />
Semaphore s = new Semaphore();<br />
cobegin<br />
/* Producer */<br />
while(true) {<br />
produce;<br />
V(s);<br />
} |<br />
/* Consumer */<br />
while(true) {<br />
P(s);<br />
consume;<br />
}<br />
coend<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.35<br />
CS134a, 2000
The <strong>bounded</strong>-<strong>buffer</strong> problem (Dijkstra 1968)<br />
• A producer produces data and adds it to a <strong>buffer</strong>.<br />
• A consumer consumes data from the <strong>buffer</strong>.<br />
• The <strong>buffer</strong> contains room for n values.<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.36<br />
CS134a, 2000
The <strong>bounded</strong>-<strong>buffer</strong> algorithm<br />
Semaphore e(n); // number of empty <strong>buffer</strong>s<br />
Semaphore f(0); // number of full <strong>buffer</strong>s<br />
Semaphore b(1); // critical section<br />
cobegin<br />
while(true) {<br />
produce;<br />
P(e); P(b);<br />
add to <strong>buffer</strong>;<br />
V(b); V(f);<br />
} |<br />
while(true) {<br />
P(f); P(b);<br />
take from <strong>buffer</strong>;<br />
V(b); V(e);<br />
consume;<br />
}<br />
coend<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.37<br />
CS134a, 2000
Implementing semaphores<br />
• Most CPUs have an atomic test-and-set instruction, or<br />
atomic exchange:<br />
int ts(int *x) { int y = *x; *x = 1; return y; }<br />
int xchg(int *x, int *y) { int z = *x; *x = *y; *y = z; }<br />
• This is used to implement a binary semaphore<br />
• void Pb(&sb) {<br />
do {<br />
int key = 0;<br />
exch(&key, sb);<br />
} while(!key);<br />
}<br />
• void Vb(&sb) { sb = 1; }<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.38<br />
CS134a, 2000
Exchange instruction<br />
XCHG—Exchange Register/Memory with Register<br />
INSTRUCTION SET REFERENCE<br />
Opcode Instruction Description<br />
87 /r XCHG r32,r/m32 Exchange doubleword from r/m32 with<br />
Description<br />
This instruction exchanges the contents of the destination (first) and source (second) operands.<br />
The operands can be two general-purpose registers or a register and a memory location. If a<br />
memory operand is referenced, the processor’s locking protocol is automatically implemented<br />
for the duration of the exchange operation, regardless of the presence or absence of the LOCK<br />
prefix or of the value of the IOPL. Refer to the LOCK prefix description in this chapter for more<br />
information on the locking protocol.<br />
This instruction is useful for implementing semaphores or similar data structures for process<br />
synchronization. Refer to Section 7.1.2., Bus Locking in Chapter 7, Multiple-Processor<br />
Management of the Intel Architecture Software Developer’s Manual, Volume 3, for more information<br />
on bus locking.<br />
The XCHG instruction can also be used instead of the BSWAP instruction for 16-bit operands.<br />
Operation<br />
TEMP ← DEST<br />
DEST ← SRC<br />
SRC ← TEMP<br />
Flags Affected<br />
None.<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.39<br />
CS134a, 2000
Normal semaphore<br />
• A normal semaphore has an integer, and two binary<br />
semaphores<br />
• struct Semaphore {<br />
int value;<br />
BinarySemaphore mutex, delay;<br />
}<br />
• P(Semaphore &s) {<br />
disable interrupts;<br />
Pb(s.mutex);<br />
s.value--; // decrement s.value by 1<br />
if(s.value < 0) { Vb(s.mutex); Pb(s.delay); }<br />
Vb(s.mutex);<br />
enable interrupts;<br />
}<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.40<br />
CS134a, 2000
Problems with semaphores<br />
• Still too low-level<br />
• Semaphore operations are scattered through code<br />
• P and V are used in pairs: how do you know which<br />
pairs match?<br />
Operating System Concepts<br />
Silberschatz and Galvin ©1999<br />
1.41<br />
CS134a, 2000