/* * BoundedBufferMon.java (Implements Producer and Consumer Using * Monitors). * * Written by : Nitin Motgi (nmotgi@cs.ucf.edu) * * This file implements producer using Monitors. By using this kind of * construct, a collection of procedures is declared to be in a monitor * and mutual exclusion is enforced on those procedures - only one * process can be executing with it's program counter in the montiro code. * Underneath the covers, this mutual exclusion is implemented with * semaphores, but all the calls to monitor routine are replaced by the * P() and V() operations by the compiler using 2nd Pass over the program * code. * * Sometimes a critical section will need to wait for another process to * do work, like a consumer encountering an empty queue. Monitors need a * blocking mechanism, which is provided by condition variables. * * 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 : BoundedBufferMon.java, v1.0.0 02/07/2001. $ * * Revision History Revisited: */ import java.util.*; import java.lang.*; /* Start of BoundedBufferMon.*/ public class BoundedBufferMon{ int nNumberOfProducers; /* Tracks # of Producers.*/ int nNumberOfConsumers; /* Tracks # of Consumers.*/ int nNumberOfSlots; /* Number of Free Slots in Buffer */ boolean bEndCondition; /* End Condition for it.*/ int nEvents; /* Basically # of items to be produced.*/ long lStartTime,lStopTime; /* Timers used to print messages during simulation.*/ int nItem; int nNumberOfItemsProduced; /* Tracks Events.*/ int nNumberOfItemsConsumed; /* Tracks Completed Events.*/ /* Synchronization Mechanism.*/ Semaphore Empty; /* Used to check buffer empty.*/ Semaphore Full; /* Trigger when buffer full.*/ Semaphore Block; /* Block Consumer piece of code.*/ Semaphore WBlock; BoundedBufferPMon Producer[]; /* Array of Producers.*/ BoundedBufferCMon Consumer[]; /* Array of Consumers.*/ /* * This function is constructor for this class. */ public BoundedBufferMon(int nNumberOfProducer, int nNumberOfConsumer, int nNumberOfSlots, int nEvents, long lStartTime){ /* Store them within this P/C controller.*/ this.nNumberOfProducers = nNumberOfProducer; this.nNumberOfConsumers = nNumberOfConsumer; this.nNumberOfSlots = nNumberOfSlots; this.nEvents = nEvents; this.lStartTime = lStartTime; /* Initialise Synchronization Mechanism.*/ Empty = new Semaphore(1); Full = new Semaphore(0); Block = new Semaphore(1); WBlock = new Semaphore(1); /* Initialise Items.*/ nItem = 0; nNumberOfItemsProduced = 0; nNumberOfItemsConsumed = 0; }/* End of BoundedBufferSem.*/ /* * This program is heart of this */ public void Start(){ /* Create all the producers and consumers.*/ Producer = new BoundedBufferPMon[nNumberOfProducers]; Consumer = new BoundedBufferCMon[nNumberOfConsumers]; /* Print the Start Time.*/ long lInterStartTime = System.currentTimeMillis(); TimeFormat Time = new TimeFormat(); System.out.println("Started using Monitors at time " + Time.formatTime(lInterStartTime - lStartTime)); /* Initialise their Environment.*/ for(int nIndex=0; nIndex < nNumberOfProducers; nIndex++){ Producer[nIndex] = new BoundedBufferPMon(nIndex+1,this); Producer[nIndex].start(); }/* End for.*/ for(int nIndex=0; nIndex < nNumberOfConsumers; nIndex++){ Consumer[nIndex] = new BoundedBufferCMon(nIndex+1,this); Consumer[nIndex].start(); }/* End For.*/ boolean bAllDead = false; while(bAllDead == false){ bAllDead = true; for(int nIndex=0; nIndex < nNumberOfProducers; nIndex++){ if(Producer[nIndex].isAlive() == true){ bAllDead = false; break; }/* End if.*/ }/* End for.*/ for(int nIndex=0; nIndex < nNumberOfConsumers; nIndex++){ if(Consumer[nIndex].isAlive() == true){ bAllDead = false; break; }/* End if.*/ }/* End for.*/ }/* End While.*/ lStopTime = System.currentTimeMillis(); System.out.println("Completed using Monitors at time " + Time.formatTime(lStopTime - lStartTime)); }/* End of Start.*/ /* * Inserts an item in the Shared memory location. This shared * location is accessible by all the producers and consumers * in the system. */ public void Insert(int nSimItem,BoundedBufferPMon pThis){ Block.P(); if(nNumberOfItemsProduced >= nEvents){ pThis.SetEndCondition(false); Block.V(); return; }/* End if.*/ while(nItem == nNumberOfSlots) Full.P(); /* SIMULATES INSERT AN ITEM IN THE SHARED LOCATION.*/ nItem++; nNumberOfItemsProduced++; if(nItem == 1) Empty.V(); Block.V(); }/* End of Insert.*/ /* * Gets the items from the shared memory location. This basically * simulates picking of data. */ public int Get(BoundedBufferCMon cThis){ WBlock.P(); /* Check if the total number of items produced by the producer are consumed.*/ if(nNumberOfItemsConsumed >= nEvents){ cThis.SetEndCondition(false); WBlock.V(); return -1; }/* End if.*/ while(nItem == 0) Empty.P(); /* SIMULATES GET ITEM FROM THE SHARED LOCATION.*/ nItem--; nNumberOfItemsConsumed++; if(nItem == nNumberOfSlots-1) Full.V(); WBlock.V(); return 1; }/* End of Get.*/ }/* End of BoundedBufferSem.*/