17.04.2014 Views

semaphores, classic problems

semaphores, classic problems

semaphores, classic problems

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

October 8, 2001<br />

• Processes and concurrent programming<br />

– Synchronization and communication<br />

– Semaphores<br />

– Basic <strong>problems</strong><br />

• Producer/consumer<br />

• Bounded buffer<br />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


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 />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


Multi-process mutual exclusion<br />

• n processes, numbered 0...n-1<br />

• Bakery algorithm: when entering the critical<br />

section<br />

– Take a number and wait<br />

– Can’t guarantee that numbers are distinct<br />

• Process with lowest process-id goes first<br />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


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 />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


Semaphores (Dijkstra 1965)<br />

• Slightly more abstract primitives<br />

• A semaphore is a non-negative integer variable<br />

with two 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<br />

allowed to access the semaphore during a P or V<br />

operation, unless the P operation is blocked.<br />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


Mutual-exclusion with <strong>semaphores</strong><br />

• Semaphore s = new Semaphore();<br />

V(s);<br />

...<br />

P(s);<br />

critical section;<br />

V(s);<br />

...<br />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


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 />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


The bounded-buffer problem (Dijkstra 1968)<br />

• A producer produces data and adds it to a buffer.<br />

• A consumer consumes data from the buffer.<br />

• The buffer contains room for n values.<br />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


The bounded-buffer algorithm<br />

Semaphore e(n); // number of empty buffers<br />

Semaphore f(0); // number of full buffers<br />

Semaphore b(1); // critical section<br />

cobegin<br />

while(true) {<br />

produce;<br />

P(e); P(b);<br />

add to buffer;<br />

V(b); V(f);<br />

} |<br />

while(true) {<br />

P(f); P(b);<br />

take from buffer;<br />

V(b); V(e);<br />

consume;<br />

}<br />

coend<br />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


Implementing <strong>semaphores</strong><br />

• Most CPUs have an atomic test-and-set<br />

instruction<br />

int ts(int *x) { int y = *x; *x = 1; return y; }<br />

• This is used to implement a binary semaphore<br />

• void Pb(sb) { while(ts(&sb)); }<br />

• void Vb(sb) { sb = 0; }<br />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


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 <strong>semaphores</strong> 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 />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001


Normal <strong>semaphores</strong><br />

struct Semaphore {<br />

int count;<br />

BinarySemaphore mutex, delay;<br />

}<br />

P(Semaphore &s) {<br />

disable interrupts;<br />

Pb(s.mutex);<br />

s.count--;<br />

if(s.count < 0) {<br />

Vb(s.mutex);<br />

Pb(s.delay);<br />

}<br />

Vb(s.mutex);<br />

enable interrupts;<br />

}<br />

V(Semaphore &s) {<br />

disable interrupts;<br />

Pb(s.mutex);<br />

s.count++;<br />

if(s.count


Problems with <strong>semaphores</strong><br />

• Still too low-level<br />

• Semaphore operations are scattered through<br />

code<br />

• P and V are used in pairs: how do you know<br />

which pairs match?<br />

Computing Systems<br />

http://www.cs.caltech.edu/cs134/cs134a October 10, 2001

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!