Exercise 5, Problem 1: Doctor and patients in monitor

  monitor Reception {
    cond in;
    cond out;
    cond check;
    cond gone; # to inform that the patient is really gone
    boolean reserved  =  true;
       
   procedure Cometoreception( ) {    #  code for a patient 
      if (reserved) wait(in);        #  wait to get in  
      else reserved = true;     #  mark  reception room reserved      
      go to the reception room 
      signal(check);    #  tell the doctor 
      examination by the doctor
      wait(out);     #  wait until allowed to leave
      leave the reception room;
      signal(gone);
   }
  
   procedure Examinepatient ( ) {   # code for the doctor
      if !empty(in) signal(in); # call a patient in if there is somebody waiting
       else reserved = false;  #if not then  mark yourself free
      wait(check); # wait for a patient to arrive o  
      examine a patient
      signal(out);   # allow a patient to leave
      wait(gone); #  waitfor the customer to really leave
      }                                                                                                                        
   } 
 
   process Patient(  )[i = 1 to n]  {
      while (true)
         do what ever you do
         feel sick
         call  Reception.Cometoreception( );       
      }
   }

   process Doctor(  ) {
      while (true)  call Reception.Examinepatient( );
    }

Exercise 5, problem 2: Barbers in the monitor

b) Simple solution for one barber

process CUSTOMER[1 to N]
{
   while (true) {
     let_your_hair_grow();
     call Barber_Shop.get_haircut();
   }
}

process BARBER
{
   while (true) {
     call Barber_Shop.get_next_customer();
     haircut();
     call Barber_Shop.finished_cut();
   }
}

The monitor from fig 5.10 ripped off to bare necessities:
=======================================================

monitor Barber_Shop
{
  int barber = 0; # chair and  open variables are not needed
  cond barber_available;
  cond chair_occupied;
  cond door_open;
  cond customer_left;

  procedure get_haircut()  
  {
     while (barber==0) wait(barber_available);
     barber = barber – 1;  
     # chair = chair +1;   
     signal(chair_occupied);
     # while(open ==0) 
     wait(door_open);
     # open=open -1;   
     signal(customer_left);
  }
    
  procedure get_next_customer()  
  {
     barber = barber + 1; signal(barber_available);
     # while (chair ==0) 
     wait(chair_occupied);
     # chair = chair -1;
  }
    
  procedure finished_cut()  
  {
     # open = open +1;
     signal(door_open);
     # while (open > 0)
     wait(customer_left);
  }
} # monitor Barber_Shop  

c) Many barbers in the barbershop

process CUSTOMER[1 to M]
{
   while (true) {
     let_your_hair_grow();
     call Barber_Shop.get_haircut();
   }
}

process BARBER[barber=1 to N] # This was changed
{
   while (true) {
     call Barber_Shop.get_next_customer(barber);
     haircut();
     call Barber_Shop.finished_cut(barber);
   }
}

monitor Barber_Shop  
{
   int n_free_barber = 0;    # number of free barbers 
   boolean free_chair[N];    # is the chair i free?  
   int barber = 1;           # identity of some free barber 
   cond chair_occupied[N];   # wait until somebody sitting in the chair
   cond door_open[N];        # wait until haircut finished
   cond barber_available;    # wait for free barber 

   procedure get_haircut() 
   {
     while (n_free_barber==0) wait(barber_available);

     while (! free_chair[barber]) 
          barber = (barber + 1) % N;  # find a free barber 
     free_chair[barber] = false;        # and reserve him
     n_free_barber--;    

     signal(chair_occupied[barber]); # wakeup the sleeping barber 
     wait(door_open[barber]);           # wait until barbering finished
   }

   procedure get_next_customer(int barber) 
   {   
     n_free_barber++;                   # free barber 
     free_chair[barber] = true;         # free chair
     signal(barber_available);     # inform the possibly waiting customers
     wait(chair_occupied[barber]); # wait for a customer to arrive 
   }
    
   procedure finished_cut(int barber)  
   {
     signal(door_open[barber]);         # customer finished
   }
} # monitor Barber_Shop

Exercise 5, problem 3: Checkpointing

chan ready_to_write(), writing_done(), proceed();

process P[0]    # coordinator
{
   while (true) {
      do_what_ever_you_do();

      for [i = 1 to N]
          receive ready_to_write();     # checkpoint: wait for the others
   
      for [i = 1 to N]
          send proceed();               # let others proceed

      save_your_own_state_to_disk(); 

      for [i = 1 to N]
          receive writing_done();       # wait until others have written 
 
      for [i = 1 to N]
         send proceed();                # let others proceed
   }
}       

process P[i = 1 to N]   # the other processes
{
    while (true) do {
      do_what_ever_you_do();


      send ready_to_write();            # inform that you are ready to write
      receive proceed();                # wait for permission to proceed

      save_your_own_state_to_disk();  

      send writing_done();              # inform thar you are ready
      receive proceed();                # wait for permission to proceed
    }
}


Exercise 5, problem  4: Message passing at Korvatunturi:


chan   arrived (),  # reindeers inform Rednose 
           ready (),   # Rednose informs Santa 
           Santatoreindeers (char);  # Santa  communicates with reindeers

process  Reindeer[i=1 to N-1] {
      while (true) {
           wander around;
           arrive at Korvatunturi;
           send arrived ();
           receive Santatoreindeers [i]();  # start
           fly around delivering presents;
           receive Santatoreindeers[i] (); # thanks
        }
    }

  process Rednose  {  # acts as coordinator 
      while (true) {
           wander around with other reindeers;
           arrive at Korvatunturi;
           for [i=1 to N-1] receive(arrived);   # wait until all N-1  have arrived
          send  ready(); # inform Santa 
           receive  Santatoreindeers[0];   # wait for Santa to start
           fly around and deliver presents;
           receive Santatoreindeers[0];    # wait for  Santa  to give thanks
        }
  }


 process Santa {
     while (true) {
           do all kind of things;
           receive ready();
           for [i=0 to N-1] send Santatoreindeers[i];
          deliver presents;
            for [i=0 to N-1] send Santatoreindeers[i];
           enjoy holiday season;
         }
   }

Exercise 5, problem 5: Shared bank account server with message passing 
chan request (int  custid, int amount,  int type);
chan reply[n] (types of results);

process BankAccountServer {
int custid; # customer  number
int amount; # amount of money for deposit or withdrawal
int type;  # type of request: withdrawal  = 1, deposit = 0
int saldo = 0;   # saldo of the account
int n, front =0, rear = n-1,  # size of the queue buffer, first in the queue, last in the buffer  
     nbr = 0;  # number of  those waiting for withdrawal
type queue [n, 2];   # queue for   those waiting for withdrawal; qamount, qcustid 

 while (true) {
       receive request (int  custid, int amount,  int type);
       if (type = = 0)  {     # deposit
           saldo = saldo + amount;   # increase saldo
           send reply[custid] ('OK'); # send OK reply to the customer
           # check, if the next waiting request can be allocated
            while (saldo > queue [front].qamount)     {# the first request in the queue
                  saldo = saldo - queue [front].qamount;  
                  send reply[queue [front].qcustid] ('OK'); # send  OK reply to the customer
                  front = (front + 1)%n;    # update the queue
                  nbr --;
            }
      else {        # withdrawal
          if (saldo > amount AND nbr = = 0) {   # enough saldo and nobody waiting
               saldo = saldo -amount;  # decrease saldo
               send reply[custid] ('OK'); #  send  OK reply to the customer 
          }
         else  {   #  put the request into the queue
              if (nbr < n)  rear = (rear + 1) / n;  {
                 queue[rear].qcustid = custid;
                 queue[rear].qamount = amount;
                 nbr ++;
            }                   # the request is in the queue; it is assumed that it can be filled  pretty soon  
                                  # the customer is informed first  when  the  there is enough money for the
                                  #  withdrawal 
                                  # it would be possible to send some warning here 
             else     # there is no more room in the queue
             send reply[custid] ('PROBLEMS');  # the customer should send the request enew 
        }  # end of withdrawal
    } end of while
}end of BankAccountServer
Exercise 5, problem 6: 
type req_kind = enum(READ, WRITE);

chan IO_request (int clientID, req_kind oper, types of arguments);
chan reply_to_read[M](types of arguments);
chan reply_to_write[M](types of arguments);

process DB_server]i=1 to N]     # N server processes using same channel
{                               # the first one takes the request
  int clientID; 
  req_kind oper; 
  variables for args;
  varibles for results;
  other local declarations;

  while (true) {
    receive IO_request(clientID, oper, args);   # wait for request

    switch(oper) {
      case READ {
        RW_controller.request_read();
        results=perform_read_operation_to_DB(args);
        RW_controller.release_read();
        send reply_to_read[clientID](results);
      }
  
      case WRITE {
        RW_controller.request_write();
        results=perform_write_operation_to_DB(args);
        RW_controller.release_write();
        send reply_to_write[clientID](results);
      }
    }  #end switch
  } 
} # end DB_server

# Monitor that takes care of the mutual exclusion  

monitor RW_Controller   # Andrews fig 5.5 (tai harj 5.1)
{
  int nr=0, nw=0; 
  cond oktoread, oktowrite;

  procedure request_read() {
     while (nw > 0) wait(oktoread);
     nr++;
  }
 
  procedure release_read() {
    nr--;
    if (nr==0) signal(oktowrite);
  }   

  procedure request_write() {
    while (nr > 0 || nw > 0) wait(oktowrite); 
    nw++;
  }
   
  procedure release_write() {
    nw--;  
    signal(oktowrite);
    signal_all(oktoread);
  }
}