typedef int semaphore;
semaphore mutex = 1;
semaphore tobacco = 0;
semaphore paper = 0;
semaphore matches = 0;
void agent(void)
{
while (TRUE) {
down(&mutex};
Select random semaphore from tobacco, paper, or matches: call this <item>;
Put missing ingredients on table;
up(&<item>);
}
}
void smoker(has tobacco)
{
while (TRUE) {
down(&tobacco);
Get ingredients from table, make cigarette smoke;
up(&mutex);
}
}
Smoker who has paper or matches can be defined similarly. This solution avoids starvation.
semaphore mutex = 1; // accessing the sliding marker
semaphore menaccess = 1, womenaccess = 1; // wait for men/women
semaphore menwait = 0, womenwait = 0; // queue to enter the bathroom
int menwaiting = 0, womenwaiting = 0; // Boolean: are there men/women waiting to enter?
int mencount = 0, womencount = 0; // number of men/women inside bathroom
string sliding_marker = "empty"; // defined in problem
void Woman(void)
{
down(womenaccess);
down(mutex)
if (sliding_marker == "men present")
up(mutex);
womenwaiting = 1;
down(womenwait); // first waiting woman blocks - rest block on womenaccess above
down(mutex);
else if (sliding_marker == "empty")
sliding_marker = "women present";
womencount++;
up(mutex);
up(womenaccess);
Use bathroom;
down(womenaccess);
down(mutex);
womencount--;
if (womencount == 0) // sliding_marker=="women present"
if (menwaiting == 1)
sliding_marker = "men present";
menwaiting = 0;
up(menwait); // wake up first waiting man
else sliding_marker = "empty"
up(mutex)
up(womenaccess);
}
void Man(void)
{
down(menaccess);
down(mutex);
if sliding_marker == "women present"
up(mutex);
menwaiting = 1;
down(menwait); // first waiting man blocks - rest block on menaccess above
down(mutex);
else if (sliding_marker == "empty")
sliding_marker = "men present";
mencount++;
up(mutex);
up(menaccess);
Use bathroom;
down(menaccess);
down(mutex);
mencount--;
if (mencount == 0) // sliding_marker=="men present"
if (womenwaiting == 1)
sliding_marker = "women present";
womenwaiting = 0;
up(womenwait); // wake up first waiting woman
else sliding_marker = "empty";
up(mutex);
up(menaccess);
}
The above solution(s) may cause starvation and/or deadlocks.
monitor Printers
condition priority[1..n];
int count[1..n];
int printers_in_use;
procedure acquire_printer(process: int);
begin
if printers_in_use = 3 then
begin
count[process] := count[process] + 1;
wait(priority[process]);
end
printers_in_use := printers_in_use + 1;
end;
procedure release_printer(process: int);
begin
printers_in_use := printers_in_use - 1;
for i := n to 1 do
if count[i] > 0 then
begin
count[i] := count[i] - 1;
signal(priority[i]);
exit;
end
end;
for i:=1 to n do count[i] := 0;
printers_in_use := 0;
end monitor;
#define free 0
#define busy 1
semaphore mutex = 1;
semaphore calvin_cust = 0, terri_cust = 0, eddie_cust = 0;
semaphore calvin_barb = 0, terri_barb = 0, eddie_barb = 0;
semaphore chairs = 0;
int waiting = 0;
void customers(void)
{
down(mutex);
if (waiting>=N){
up(mutex); /* exit the shop */
exit;
}
else if (waiting>0){
waiting++; /* wait in the chairs */
up(mutex);
down(chairs);
checkbarberswithpriority();
} /* no one is waiting - some barber may be free */
else checkbarberswithpriority();
else{ /* all barbers busy - take chair */
waiting++; /* wait in the chairs */
up(mutex);
down(chairs);
checkbarberswithpriority();
}
}
void checkbarberswithpriority(){
down(mutex);
if (calvin==free){ /* check barbers in order of priority */
up(calvin_cust); /* wake up barber */
calvin=busy;
up(mutex);
down(calvin_barb); /* the customer waits for the barber */
get_haircut();
}
else if (terri==free){
up(terri_cust);
terri=busy;
up(mutex);
down(terri_barb);
get_haircut();
}
else if (eddie==free){
up(eddie_cust);
eddie=busy;
up(mutex);
down(eddie_barb);
get_haircut();
}
}
Code for Calvin is as follows.
void calvin(void)
{
while (TRUE) {
down(mutex);
if(waiting>0)
up(chairs); /* wake up some customer */
waiting--;
calvin=free;
up(mutex);
down(calvin_cust); /* sleep. zzz. */
down(mutex); /* barber woken up */
up(calvin_barb); /* the barber gets the customer */
up(mutex);
cut_hair();
}
}
Code for terri() and eddie() are similar.
Caveat: the above solution might cause starvation - under some circumstances,
a customer may leave the shop without being serviced.