AlarmClock: Monitor;
var now: interger;
var wakup: condition;
procedure tick()
begin
now++;
wakeup.signal(); // wake
up earliest waiter on each tick
end
procedure wakeme(interval: integer)
var AlarmSetting: integer;
begin
AlarmSetting := now + interval;
while (now < AlarmSetting)
do
wakeup.wait(AlarmSetting);
wakeup.signal(); // in case
more than one process should wake up
end
//initialization code
begin
now := 0;
end
#2
Assume that a notifier keeps the monitor lock (mutex), at least until
the end of the procedure.
For each monitor m, use a semaphore mutex, initialized to 1.
For each condition variable cv in m, use a semaphore cv-delay, initialized
to 0 and a integer cv-counter, also initialized to 0.
procedure entry()
begin
P(mutex);
end
procedure exit()
begin
V(mutex);
end
procedure wait()
begin
cv-count := cv-count + 1;
V(mutex);
P(cv-delay);
P(mutex);
end
Procedure notify()
begin
if (cv-count > 0) then
begin
cv-count := cv-count – 1;
V(cv-delay);
end
end
#3
Bounded_Semaphore: Monitor
var s: integer;
var c1, c2: condition;
procedure P()
begin
while (s <= 0) c1.wait();
s--;
c2.notify();
end
procedure V()
begin
while (s >= smax) c2.wait();
s++;
c1.notify();
end
//initialization code
begin
s = smax;
end
#4
ChunkingSemaphore: Monitor;
var count: interger;
var more: condition;
procedure P(n: integer)
begin
while (count < n) do
more.wait(n);
count := count – n;
if (count > 0) then
more.signal();
end
procedure V(n: integer)
begin
count := count + n;
more.signal();
end
//Initialization code
begin
count := initialCount;
end
#5
The idea here is to take advantage of priorities – the amount of time a particular thread is willing to wait is encoded in its priority value.
TimeoutBinarySemaphore: Monitor
var busy: boolean;
var time: integer;
var w: condition;
procedure tick()
begin
time := time + 1;
w.signal();
end
procedure V()
begin
busy := false;
w.signal();
end
procedure P(t: integer, v: boolean)
var timeout: integer;
begin
timeout = time + t;
while (busy && (time
< timeout)) do
w.wait(timeout);
if (busy) then
v := false;
w.signal(); //cascade down to other waiting threads
else
v := true;
busy := true;
end
//initialization
begin
busy := false;
time := 0;
end