/* 
 * Synch.java (This file simulates synchronization methods
 *             like Dining Philosophers, Readers/Writers and 
 *             BoundedBuffer Problem using Semaphores, Monitors 
 *             and Event Notification.) 
 *
 * Written by : Nitin  Motgi (nmotgi@cs.ucf.edu)
 *
 * This class initiates all the experiments by creating a class and
 * passing the parameters required to start the experiment for all the
 * above methods and then Start()  method present in each experiment
 * to start. Timers are re-intialised when new experiement using 
 * semaphore, event notification and monitors is started.
 * 
 * Portions copyright(c) 2000 to School of Electrical Engineering and 
 * Computer Science, UCF, Orlando.                   
 *
 * Use and distribution of this source code are strictly governed by 
 * terms and conditions set by the authors.
 * 
 * $Id : Synch.java, v1.0.0 02/07/2001. $
 *
 * Revision History:
 *
 * 1. Created Basic structure.        Nitin,        v1.0.0  02/07/2001.
 * 2. Added documentation,            Nitin,        v1.0.1  02/07/2001.      
 * 3. Added all Testing functions,    Nitin,        v2.0.0  02/15/2001.      
 * 4. Added kbhit() function,         Nitin,        v2.1.0  02/16/2001.    
 * 5. Modified Documentation,         Nitin,        v2.1.1  02/16/2001.
 * 6. Performed Integrity Check,      Nitin,        v2.2.1  02/16/2001.
 * 7. Final Documentation Check,     
 * 8. Final Variable Name Check,
 * 9. Final Functionality Check.
*/

/* Import some of the libraries.*/
import java.lang.*;
import java.util.*;

/*****************************************************************************
 * Class Synch.
 * Description : Main function that starts the experiments for Dining 
 *               philosopher, Readers/Writers and Bounded Buffer Problem using
 *               Semaphore,Monitor and Event notification using Observer/
 *               Observable in Java.
 * Functions   : public static void main(String[] szArgs) and
 *               public static void kbhit()
 ****************************************************************************/
public class Synch{
     
     /* Initiates the Synch experiments.*/
     public static void main(String[] szArgs){
      long lStartTime = System.currentTimeMillis(); /* Stamps the current
                                                       time.*/

      /* Command Line integrity check.*/
      if(szArgs.length < 2){
        System.out.println("** ERROR : less number of parameters.");
        System.out.println("Usage : java Synch <Y=number of threads>"+
                           " <Z=number of events>");
        return;
      }/* End if.*/

      /* Retrieves command line parameters.*/
      int nYParam = Integer.parseInt(szArgs[0]);
      int nZParam = Integer.parseInt(szArgs[1]);

      /* Perform Parameter integrity Check.*/
      if(nYParam <= 1){
       System.out.println("** ERROR : <Y = number of threads> cannot be" +
                          " less than or equal to one.");
       System.out.println("Usage : java Synch <Y=number of threads>"+
                          " <Z=number of events>");
       return;
      }/* End if.*/

      if(nZParam <= 0){
       System.out.println("** ERROR : <Z = number of events> cannot be" +
                          " less than or equal to zero.");
       System.out.println("Usage : java Synch <Y=number of threads>"+
                          " <Z=number of events>");
       return;
      }/* End if.*/

      /* Once at parameters are filtered, we can create experiments and
         run them.*/

      /***********************************************************************
       * DINING PHILOSOPHER :
       * With Semaphore,
       * With Monitor and
       * With Event Notification using Observer/Observable Class.
       **********************************************************************/
      System.out.println("Dining Philosophers started at time 0.0 with "+
                         nYParam + " Philosophers");
      DiningPhilosopher DPhil = new DiningPhilosopher(nYParam,
                                                      nZParam,
                                                      lStartTime);
      DPhil.Start();
      DiningPhilosopherMon DPhilMon = new DiningPhilosopherMon(nYParam,
                                                               nZParam,
                                                               lStartTime);
      DPhilMon.Start();
      DiningPhilosopherObs DPhilObs = new DiningPhilosopherObs(nYParam,
                                                               nZParam,
                                                               lStartTime);
      DPhilObs.Start();
      System.out.print("Press any key to continue... "); 
      kbhit();

      /***********************************************************************
       * BOUNDED BUFFER :
       * With Semaphore,
       * With Monitor and
       * With Event Notification using Observer/Observable Class.
       **********************************************************************/
      lStartTime = System.currentTimeMillis();
      System.out.println("Bounded Buffer started at time 0.0 with " +
                         nYParam + " Producers and " + (int)nYParam/2 + 
                         " Consumers buffer size = " + nYParam);
      BoundedBufferSem BBSem = new BoundedBufferSem(nYParam,
                                                    (int)(nYParam/2),
                                                    nYParam, 
                                                    nZParam,
                                                    lStartTime);
      BBSem.Start();
      BoundedBufferMon BBMon = new BoundedBufferMon(nYParam,
                                                    (int)(nYParam/2),
                                                    nYParam, 
                                                    nZParam,
                                                    lStartTime);
      BBMon.Start();
      BoundedBufferObs BBObs = new BoundedBufferObs(nYParam,
                                                    (int)(nYParam/2),
                                                    nYParam, 
                                                    nZParam,
                                                    lStartTime);
      BBObs.Start();
      System.out.print("Press any key to continue...  "); 
      kbhit();
      
      /***********************************************************************
       * READERS/WRITERS :
       * With Semaphore,
       * With Monitor and
       * With Event Notification using Observer/Observable Class.
       **********************************************************************/
      lStartTime = System.currentTimeMillis();
      System.out.println("Reader Writer started at time 0.0 with "+
                         nYParam + " Readers and " + (int)(nYParam*1.5) + " Writers");

      ReaderWriterSem  RWSem = new ReaderWriterSem(nYParam,
                                                   (int)(nYParam*1.5),
                                                   nZParam,
                                                   lStartTime);
      RWSem.Start();
      ReaderWriterMon  RWMon = new ReaderWriterMon(nYParam,
                                                   (int)(nYParam*1.5),
                                                   nZParam,
                                                   lStartTime);
      RWMon.Start();
      ReaderWriterObs  RWObs = new ReaderWriterObs(nYParam,
                                                   (int)(nYParam*1.5),
                                                   nZParam,
                                                   lStartTime);
      RWObs.Start();
      System.out.print("Press any key to continue...  "); 
      kbhit();
     }/* End main.*/

     /* Performs blocked wait on keyboard till some key is pressed.
        upon reception of enter key, only one key is evaluated and
        others are left/omitted.*/
     public static void kbhit(){
      try{
       System.in.read();
       System.in.skip(System.in.available());
      }catch(Exception e){}
       System.out.println("");
     }/* End of kbhit.*/

}/* End of Synch.*/

