/* * ReaderWriterSem.java (Implements Readers/Writers Using Semaphores). * * Written by : Nitin Motgi (nmotgi@cs.ucf.edu) * * 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 : ReaderWriterSem.java, v1.0.0 02/07/2001. $ * * Revision History Revisited: * */ import java.util.*; import java.lang.*; /* Start of ReaderWriterSem.*/ public class ReaderWriterSem{ int nNumberOfWriters; /* Tracks # of Writers.*/ int nNumberOfReaders; /* Tracks # of Readers.*/ boolean bEndCondition; /* End Condition for it.*/ int nEvents; /* Basically # of writes.*/ long lStartTime,lStopTime; /* Timers used to print messages during simulation.*/ int nReaderCount; /* Number of readers currently in the critical section.*/ int nReads; /* # of current reads.*/ int nWrites; /* # of current writes.*/ int nTok; /* current token number.*/ int nInsRead; /* # of readers read.*/ /* Synchronization Mechanism.*/ Semaphore Mutex; /* This is basically used to protect the counter.*/ Semaphore DB; /* Used to protect database.*/ Semaphore Block; /* Block piece of code.*/ Semaphore WBlock; /* Same here.*/ Semaphore RBlock; /* Same here.*/ ReaderWriterWSem Writer[]; /* Array of Writers.*/ ReaderWriterRSem Reader[]; /* Array of Readers.*/ /* * This function is constructor for this class. */ public ReaderWriterSem( int nNumberOfWriter, int nNumberOfReader, int nEvents, long lStartTime){ /* Store them within this P/C controller.*/ this.nNumberOfWriters = nNumberOfWriter; this.nNumberOfReaders = nNumberOfReader; this.nEvents = nEvents; this.lStartTime = lStartTime; /* Initialise Synchronization Mechanism.*/ Mutex = new Semaphore(1); DB = new Semaphore(1); Block = new Semaphore(1); WBlock = new Semaphore(1); RBlock = new Semaphore(1); nReaderCount = 0; nReads = 0; nWrites = 0; nTok = 0; nInsRead = nNumberOfReaders; }/* End of BoundedBufferSem.*/ /* * This program is heart of this */ public void Start(){ /* Create all the producers and consumers.*/ Writer = new ReaderWriterWSem[nNumberOfWriters]; Reader = new ReaderWriterRSem[nNumberOfReaders]; /* Print the Start Time.*/ long lInterStartTime = System.currentTimeMillis(); TimeFormat Time = new TimeFormat(); System.out.println("Started using Semaphores at time " + Time.formatTime(lInterStartTime - lStartTime)); /* Initialise their Environment.*/ for(int nIndex=0; nIndex < nNumberOfWriters; nIndex++){ Writer[nIndex] = new ReaderWriterWSem(nIndex+1,this); Writer[nIndex].start(); }/* End for.*/ for(int nIndex=0; nIndex < nNumberOfReaders; nIndex++){ Reader[nIndex] = new ReaderWriterRSem(nIndex+1,this); Reader[nIndex].start(); }/* End For.*/ boolean bAllDead = false; while(bAllDead == false){ bAllDead = true; for(int nIndex=0; nIndex < nNumberOfWriters; nIndex++){ if(Writer[nIndex].isAlive() == true){ bAllDead = false; break; }/* End if.*/ }/* End for.*/ for(int nIndex=0; nIndex < nNumberOfReaders; nIndex++){ if(Reader[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.*/ /* * Reads the database and each reader reads a write value only * once. */ int ReadDatabase(int nMyToken, ReaderWriterRSem rThis){ Block.P(); /* Block this section of code using semaphores.*/ if(nReads == nEvents*nNumberOfReaders){ rThis.SetEndCondition(false); Block.V(); return -2; }/* End if.*/ /* Check if the Token Match.*/ RBlock.P(); if(nMyToken == nTok){ /* Means he has already this value, so don't allow him to read the value again.*/ RBlock.V(); Block.V(); return 1; }/* End if.*/ rThis.nToken = nTok; RBlock.V(); Mutex.P(); /* Acquire Lock for Incrementing reader count.*/ nReaderCount++; if(nReaderCount == 1) DB.P(); Mutex.V(); /* Release Lock.*/ /* SIMULATE READ DATABASE HERE.*/ RBlock.P(); nInsRead++; nReads++; RBlock.V(); Mutex.P(); nReaderCount--; if(nReaderCount == 0) DB.V(); Mutex.V(); Block.V(); return 1; }/* End of ReadDatabase.*/ /* * Writes the values to the database. */ void WriteDatabase(ReaderWriterWSem wThis){ WBlock.P(); if(nWrites == nEvents){ wThis.SetEndCondition(false); WBlock.V(); return; } RBlock.P(); if(nInsRead != nNumberOfReaders){ RBlock.V(); WBlock.V(); return; }else{ nInsRead = 0; } RBlock.V(); /* SIMULATE CREATE DATABASE RECORD.*/ DB.P(); /* SIMULATE WRITE RECORD TO DATABASE.*/ nTok++; nWrites++; DB.V(); WBlock.V(); }/* End of WriteDatabase.*/ }/* End of ReaderWriterSem.*/