package edu.vt.marian.common; /** This class provides a moniter object for thread coordination. It supports multiple readers/single writer mode. uses the services of class(es): ReaderWriterMutex(Debug debug) ReaderWriterMutex(int reader_limit, Debug debug) void read_enter() void read_exit() void writer_enter() void writer_exit() int get_max_active_reader_number() int set_max_active_reader_number(int reader_limit) designer(s): Jianxin Zhao (jxzhao@csgrad.cs.vt.edu) implementator(s): Pingang Wang (pwang@csgrad.cs.vt.edu) finished time: 11/23/98 known bugs: None JDK version: JDK 1.1.5 side effects: Unknown */ public class ReaderWriterMutex { // this variable stores current number of active readers private int active_reader_number; // this variable stores the limit of active readers private int max_active_reader_number; // this flag indicates if there's an active writer in the critical region private boolean writer_active; // this flag indicates if there're some writer waiting to enter the critical region private boolean writer_waiting; // debug object private Debug debug; /** method name: ReaderWriterMutex method description: constructor of ReaderWriterMutex class uses the services of class(es): input parameter(s): Debug - debug object output parameter(s): none return value: none synchronization consideration: */ public ReaderWriterMutex(Debug debug) { this.debug = debug; // set max active reader to default value max_active_reader_number = 0x7fffffff; // MAX_INTEGER // initialize flags active_reader_number = 0; writer_active = false; writer_waiting = false; } /** method name: ReaderWriterMutex method description: constructor of ReaderWriterMutex class uses the services of class(es): input parameter(s): int reader_limit - cocurrent reader limit Debug debug - debug object output parameter(s): none return value: none synchronization consideration: */ public ReaderWriterMutex(int reader_limit, Debug debug) { this.debug = debug; // check if the limit is in proper range (>0) if (reader_limit > 0) { max_active_reader_number = reader_limit; } else { debug.dumpTrace("negative reader_limit identified"); max_active_reader_number = 0x7fffffff; // MAX_INTEGER } active_reader_number = 0; writer_active = false; writer_waiting = false; } /** method name: reader_enter method description: This method is called when a reader enters the critical section. uses the services of class(es): input parameter(s): none output parameter(s): none return value: none synchronization consideration: */ public synchronized void reader_enter() { // the reader will be put into the waiting queue in any of these cases: // 1. there's an active writer // 2. there're writers waiting to enter the critical region // 3. maximum active reader limit is reached while (writer_active || writer_waiting || (active_reader_number >= max_active_reader_number)) { try { wait(); } catch (InterruptedException e) { debug.dumpTrace("exception caught in method reader_enter wait()"); } } // reader gets permit to enter the critical region active_reader_number ++; } /** method name: reader_exit method description: This method is called when a reader exits the critical section. uses the services of class(es): input parameter(s): none output parameter(s): none return value: none synchronization consideration: */ public synchronized void reader_exit() { // check for error: no writer & reader can enter simultaneously if (writer_active) { debug.dumpTrace("Error 2: Writer active while reader exit"); return; } // check if there's error in counting active reader if (active_reader_number == 0) { debug.dumpTrace("Error 3: Reader number < 0"); return; } // reduce the number of activer reader active_reader_number --; // wake up all waiting threads notifyAll(); } /** method name: writer_enter method description: This method is called when a writer enters the critical section. uses the services of class(es): input parameter(s): none output parameter(s): none return value: none synchronization consideration: */ public synchronized void writer_enter() { // the writer will be paused if there're active readers or writer while ((active_reader_number > 0) || writer_active) { // if there're active readers, set writer waiting flag if (active_reader_number > 0) { writer_waiting = true; } try { wait(); } catch (InterruptedException e) { debug.dumpTrace("exception caught in method writer_enter wait()"); } } // set writer status flags writer_waiting = false; // it might not be writer_active = true; } /** method name: writer_exit method description: This method is called when a writer exits the critical section. uses the services of class(es): input parameter(s): none output parameter(s): none return value: none synchronization consideration: */ public synchronized void writer_exit() { // check for error: no writer & reader can enter simultaneously if (active_reader_number != 0) { debug.dumpTrace("Error 4: reader entered before writer exit"); } // check if writer active flag is correctly set if (writer_active == false) { debug.dumpTrace("Error 5: Wrong Write Active flag"); } // clear writer active flag writer_active = false; // wake up all waiting threads notifyAll(); } /** method name: get_max_active_reader_number method description: Return the limit of active readers. uses the services of class(es): input parameter(s): none output parameter(s): none return value: limit of active readers synchronization consideration: */ public int get_max_active_reader_number() { return max_active_reader_number; } /** method name: get_max_active_reader_number method description: Set the limit of active readers. uses the services of class(es): input parameter(s): int reader_limit - active reader limit output parameter(s): none return value: none synchronization consideration: */ public int set_max_active_reader_number(int reader_limit) { final int SUCCESS = 0; final int FAIL = -1; if (reader_limit <= 0) { debug.dumpTrace("negative reader_limit identified"); return FAIL; } max_active_reader_number = reader_limit; return SUCCESS; } }