13.07.2015 Views

An Operating Systems Vade Mecum

An Operating Systems Vade Mecum

An Operating Systems Vade Mecum

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.

Mechanisms 283they deal with different event counts. This solution allows the bounded buffer to be usedsimultaneously by both activities because it guarantees that the very same datum willnever be touched by both at once.The other tool we will use is the sequencer, which assigns an arbitrary order tounordered events. We will use this order to decide which activity gets a resource first. Asequencer is implemented as a non-decreasing integer variable, initialized to 0. It hasonly one operation: Ticket.Ticket(S) returns the current value of the sequencer S (initially 0) and then incrementsS. This operation is atomic. We need some form of mutual exclusion toimplement Ticket because no two calls may return the same value.Now we can implement a producer-consumer situation in which there are manyproducers. For simplicity, we will still have only one consumer. As before, consumptionand production need not exclude each other. However, two producers must take turns tomake sure that they don’t write into the same cell in the Buffer. Here is the new producerprogram.1 ...2 var3 Turn : sequencer;45 activity Producer;6 var7 SequenceNumber : integer;8 Value : Datum;9 begin10 loop11 ... { compute Value }12 SequenceNumber := Ticket(Turn); { discover turn }13 Await(In reaches SequenceNumber); { wait for turn }14 Await(Out reaches SequenceNumber − Size + 1);15 { wait for Buffer }16 Buffer[SequenceNumber mod Size] := Value;17 Advance(In);18 end;19 end Producer;Each producer must wait until it is its turn to produce. The call to Ticket in line 12 ordersactive producers. Usually there will be no wait in line 13, unless another producer hasjust grabbed an earlier ticket and has not yet gotten to line 17. The Await in line 14 is tomake sure that the cell in Buffer that is about to be overwritten has been consumed. Itdiffers from line 16 of the previous example by 1, since here SequenceNumber starts at0, not 1. The Advance in line 17 tells waiting consumers that this cell in Buffer may beconsumed, and it tells waiting producers that we have finished our turn.The call to Await in line 13 might seem unnecessary. It’s there to make sure thatproducers write cells of Buffer in order, so that consumers may assume that when In isadvanced in line 17, the next cell of Buffer has new data. Unfortunately, one effect ofthis imposed sequential behavior on producers is that separate cells of Buffer cannot bewritten simultaneously. If the data are large, producers may exclude each other for along time.We promised earlier that a semaphore could be built with event counts andsequencers. Here is an implementation:

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

Saved successfully!

Ooh no, something went wrong!