Skip to content

Instantly share code, notes, and snippets.

@zane
Created February 23, 2009 00:37
Show Gist options
  • Save zane/68706 to your computer and use it in GitHub Desktop.
Save zane/68706 to your computer and use it in GitHub Desktop.
class Ticketing {
Entering: array [1..N] of boolean = {false};
Number: array [1..N] of integer = {0};
void lock(integer i) {
Entering[i] = true;
Number[i] = 1 + max(Number[1], ..., Number[N]);
Entering[i] = false;
for (j = 1; j <= N; j++) {
// Wait until thread j receives its number:
while (Entering[j]) { /* nothing */ }
// Wait until all threads with smaller numbers or with the same
// number, but with higher priority, finish their work:
while ((Number[j] != 0) && ((Number[j], j) < (Number[i], i))) {
/* nothing */
}
}
}
void unlock(integer i) {
Number[i] = 0;
}
int emptySeat() {
return { index of first nonzero element in number }
}
}
monitor class BarberShop {
integer availableSeats = N;
condition customerCondition = condition();
boolean customerReady = false;
condition barberCondition = condition();
boolean barberReady = false;
condition rendezvousCondition = condition();
boolean rendezvous = false;
void waitForCustomer() {
while (!customerReady) customerCondition.wait();
customerReady = false;
}
void customerReady() {
customerReady = true;
customerCondition.signal();
}
void waitForBarber() {
while (!barberReady) barberCondition.wait();
barberReady = false;
}
void barberReady() {
barberReady = true;
barberCondition.signal();
}
void waitForRendezvous() {
while (!rendezvous) rendezvousCondition.wait();
rendezvous = false;
}
void signalRendezvous() {
rendezvous = true;
rendezvousCondition.signal();
}
boolean enterShop() {
if (availableSeats > 0) {
availableSeats--;
return true;
}
return false;
}
void leaveShop() {
availableSeats++;
}
}
class Customer {
BarberShop monitor;
Customer(BarberShop monitor, Ticketing ticketing) {
this.monitor = monitor;
this.ticketing = ticketing;
}
void run() {
if (monitor.enterShop()) {
int index = ticketing.emptySeat();
ticketing.lock(index);
monitor.customerReady();
monitor.waitForBarber();
// getting a haircut
monitor.waitForRendezvous();
ticketing.unlock(index);
monitor.leaveShop();
}
}
}
class Barber {
BarberShop monitor;
Barber(BarberShop monitor) {
this.monitor = monitor;
}
void run() {
while(true) {
monitor.waitForCustomer();
monitor.barberReady();
// cutting hair
monitor.signalRendezvous();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment