/* * BoundedBufferSem.java (Implements Producer and Consumer Using Semaphores). * * Written by : Nitin Motgi (nmotgi@cs.ucf.edu) * * This file implements producer using semaphores.This puts the data * into the buffer and other side which is consumer removes from it. * The buffer has finite size so the producer has to wait when it's * full, and the consumer has to wait when it's empty. And, of course * all elements added to the queue by the producer must be seen by * the consumer exactly once. * * 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 : BoundedBufferSem.java, v1.0.0 02/07/2001. $ * * Revision History Revisited: */ import java.util.*; import java.lang.*; /* Start of BoundedBufferSem.*/ public class BoundedBufferSem{ 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 Mutex; /* This is basically used to protect the database.*/ Semaphore Empty; /* Used to check buffer empty.*/ Semaphore Full; /* Trigger when buffer full.*/ Semaphore Block; /* Block Consumer piece of code.*/ Semaphore WBlock; BoundedBufferPSem Producer[]; /* Array of Producers.*/ BoundedBufferCSem Consumer[]; /* Array of Consumers.*/ /* * This function is constructor for this class. */ public BoundedBufferSem(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.*/ Mutex = new Semaphore(1); Empty = new Semaphore(nNumberOfSlots); 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 BoundedBufferPSem[nNumberOfProducers]; Consumer = new BoundedBufferCSem[nNumberOfConsumers]; /* Print the Start Time.*/ long lInterStartTime = System.currentTimeMillis(); TimeFormat Time = new TimeFormat(); System.out.println("Started using Semaphores at time " + Time.formatTime(lInterStartTime - lStartTime)); for(int nIndex=0; nIndex < nNumberOfConsumers; nIndex++){ Consumer[nIndex] = new BoundedBufferCSem(nIndex+1,this); Consumer[nIndex].start(); }/* End For.*/ /* Initialise their Environment.*/ for(int nIndex=0; nIndex < nNumberOfProducers; nIndex++){ Producer[nIndex] = new BoundedBufferPSem(nIndex+1,this); Producer[nIndex].start(); }/* End for.*/ boolean bAllDead = true; 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 Semaphores at time " + Time.formatTime(lStopTime - lStartTime)); }/* End of Start.*/ /* * Produce and item needed by the Producer. The item is basically * a count which has unqiue ID. */ public int ProduceItem(BoundedBufferPSem pThis){ /* PRODUCE AN ITEM.*/ WBlock.P(); if(nNumberOfItemsProduced >= nEvents){ pThis.SetEndCondition(false); WBlock.V(); return -1; }/* End if.*/ /* Produce an item and update global items produced by all the producers.*/ nItem++; nNumberOfItemsProduced++; WBlock.V(); return (1); }/* End ProduceItem.*/ /* * Inserts an item into the Shared Buffer. */ public void InsertItem(int nItem){ /* INSERT AN ITEM IN THE SHARED BUFFER.*/ /* NOTE : This part is just simulated. Here there is nothing has been inserted into the buffer. But, it'a all ready to insert any item in the shared buffer.*/ }/* End of InsertItem.*/ /* * Gets an Item from the shared Buffer. */ public int GetItem(){ /* REMOVE AN ITEM FROM THE SHARED BUFFER.*/ /* NOTE: There is nothing that is removed from here, just counts are updated. */ return 1; }/* End of GetItem.*/ /* * Consume Item will just display the ID. */ public void ConsumeItem(int nItem,BoundedBufferCSem cThis){ /* Makes a check on number of items to be consumed is equal to the total number of events that were produced.*/ if(nNumberOfItemsConsumed == nEvents){ cThis.SetEndCondition(false); }else{ /* CONSUME AN ITEM.*/ /* NOTE : This piece of code simulates Cosume Item for the cosumer.*/ nNumberOfItemsConsumed++; }/* End if.*/ }/* End of ConsumeItem.*/ /* * */ public boolean ConsumeCheck(){ if(nNumberOfItemsConsumed == nEvents) return true; else return false; }/* End of ConsumeCheck.*/ }/* End of BoundedBufferSem.*/