monitors
We start with a simple counter that can be incremented and decremented. We use the syntax of the above paper.
Counter : monitor begin value : int; procedure increment(result number : int) begin value := value + 1; number := value; end procedure decrement(result number : int) begin value := value - 1; number := value; end value := 0; end
Next, we implement a resource that can be acquired and released.
Resource : monitor begin available : boolean; free : condition; procedure acquire() begin if (not available) free.wait; available := false; end procedure release() begin available := true; free.signal; end available := true; end
Note this is a binary semaphore. A general semaphore can be implemented as follows.
Semaphore : monitor begin value : int; free : condition; procedure P() begin if (value == 0) free.wait; value := value - 1; end procedure V() begin value := value + 1; free.signal; end value := 0; end
Let us now implement a bounded buffer of size N.
BoundedBuffer : monitor begin buffer : int[]; count : int; // number of items in the buffer next : int; // index within the array where to store the next item empty : condition; full : condition; procedure put(value : int) begin if (count == N) full.wait; buffer[next] := value; next := (next + 1) mod N; count := count + 1; empty.signal; end procedure get(result value : int) begin if (count == 0) empty.wait; value := buffer[(current - count) mod N]; count := count - 1; full.signal; end count := 0; next := 0; end
Let us solve the readers-writers problem where
ReadersAndWriters : monitor begin readers : int; // number of processes that (want to) read writing : boolean; // is a process writing? procedure startRead() begin readers := readers + 1; if (writing) read.wait; read.signal; end procedure stopRead() begin readers := readers - 1; if (readers == 0) write.signal; end procedure startWrite() begin if (readers > 0 || writing) write.wait; writing := true; end procedure stopWrite() begin writing := false; read.signal; if (readers == 0) write.signal; end readers := 0; writing := false; end
Finally, we address the dining philosophers problem.
Table : monitor begin fork : boolean[]; philosopher : condition[]; procedure getForks(int i) begin while (!fork[i] || !fork[(i + 1) mod N]) philosopher[i].wait; fork[i] := false; fork[(i + 1) mod N] := false; end procedure putForks(int i) begin fork[i] := true; fork[(i + 1) mod N] := true; philosopher[(i - 1) mod N].signal; philosopher[(i + 1) mod N].signal; end fork[i] := true for i = 0, ..., N-1 end
monitors.txt · Last modified: 2009/04/26 19:31 by franck