Barbershop – Second Attempt

 

(* This implementation solves the problem identified in the first attempt.  Notice that

each customer is assigned a customer number and when a signal takes place where

there is a possibility of freeing the wrong customer, the customer number is used to

select the right one.  Notice the level of difficulty that was added to solve this one

little problem.  You face problems like this all the time in operating systems. *)

 

program barbershop_2;

 

var   max_capacity, sofa, barber_chair, cust_ready, payment, receipt, coord, mutex1

       mutex2, mutex3 : semaphore;

       finished, leab_b_chair, receipt : array[1..50] of semaphore;

       count : integer;

 

procedure customer;            procedure barber;                     procedure cashier;

 

var custnr : integer;             var b_cust : integer;                  var c_cust : integer;

begin                                  repeat                                      repeat

wait(max_capacity);

   enter shop;                      wait(cust_ready);                      wait(payment);

   wait(mutex1);                  wait(mutex2);                          wait(mutex3);

   count := count + 1;         dequeue1(b_cust);                    dequeue2(c_cust);

   custnr := count;               signal(mutex2);                        signal(mutex3);

   signal(mutex1);                wait(coord);                             wait(coord);

   wait(sofa);                          cut hair                                  accept pay;

       sit on sofa;                   signal(coord);                           signal(coord);

       wait(barber_chair);        signal(finished[b_cust]);            signal(receipt[c_cust]);

       get up from sofa;          wait(leave_b_chair[b_cust]);

   signal(sofa);                    signal(barber_chair);                 until forever;   

   sit in barber chair;

   wait(mutex2);                  until forever;

   enqueue1(custnr);

   signal(cust_ready);

   signal(mutex2);

   wait(finished[custnr]);

   leave barber chair;           

   signal(leave_b_chair[custnr]);

   pay;

   wait(mutex3);

   enqueue2(custnr);

   signal(payment);

   signal(mutex3);

   wait(receipt[custnr]);

   exit shop;

signal(max_capacity);

end;

 

begin (* main program executable code *)

   max_capacity := 20; sofa := 4; barber_chair := 3; cust_ready := 0; payment := 0;

   coord := 3; mutex1 := 1; mutex2 := 1; mutex3 := 1; count := 0;

   for i := 1 to 50 do

       begin

          finished[i] := 0; leave_b_chair[i] := 0; receipt[i] := 0;

       end; (* semaphore and integer initializations *)

   cobegin

       customer; customer; customer … (* 50 times – or 50 customers *)

       barber; barber; barber   (* 3 barbers *)

       cashier                         (* 1 cashier *)

   coend;

end.