scorej
Class OmarClock

java.lang.Object
  |
  +--scorej.OmarClock
All Implemented Interfaces:
java.lang.Runnable
Direct Known Subclasses:
NonSimulationClock, SimulationClock

public abstract class OmarClock
extends java.lang.Object
implements java.lang.Runnable

A clock object that manages the simulation time for a ScoreJ simulation. OmarClock maintains the current simulation time and is in charge of advancing time. A static OmarClock object is a field of S.java, that is accessible to the whole simulation. This static OmarClock object is crated by Scenario.initialize, which also starts a corresponding Thread which executes OmarClock's run() method. A clock can also be started by calling the S functions S.createClock(), S.setClock(), and S.runClock().

OmarClock is an abstract class. There are two implemetation classes, SimulationClock and NonSimulationClock. Each implementation class has a different implementation of sleeping, signal processor control, and the main clock thread.

Synchronization done using Doug Lea's util.concurrent package, specifically, the Semaphore class.

All procedures that get executed as part of a ScoreJ scenario must be registered with the clock using the addThread method. The OmarClock keeps a hashtable of executing Threads and Process objects. A Process object holds that Thread's current state, and a Semaphore used to wake and suspend the Thread. A Thread can be in one of 7 states:

The OmarClock can be in one of 5 states:

See the implementation classes SimulationClock.java and NonSimulationClock.java for details on the two available clocks.

See Also:
SimulationClock,


Nested Class Summary
protected  class OmarClock.Process
          Internal class that holds the status of a process in state, and a Semaphore to sync on
protected  class OmarClock.StatusObj
          Holder class that stores the Status of the OmarClock and provides symchronized accessor functions.
 
Field Summary
protected  EDU.oswego.cs.dl.util.concurrent.Semaphore _clockSync
           
protected  EDU.oswego.cs.dl.util.concurrent.Mutex _isSleepingSync
           
protected  EDU.oswego.cs.dl.util.concurrent.Semaphore _pausedSync
           
protected  long _pauseTime
           
protected  boolean _realTime
           
protected  double _realTimeFactor
           
protected  java.util.HashMap _resourceMap
           
protected  SignalProcessor _sigProc
           
protected  boolean _sleeping
           
protected  EDU.oswego.cs.dl.util.concurrent.Mutex _stateChangedSync
           
protected  OmarClock.StatusObj _status
           
protected  java.util.Hashtable _statusTable
           
protected  EDU.oswego.cs.dl.util.concurrent.Mutex _statusTableSync
           
protected  java.lang.Thread _thread
           
protected  double _time
           
protected  long _zeroTime
           
static double DEAD
           
static int INITIALIZED
           
static int KILLED
           
static int PAUSED
           
static int RUNNING
           
static double SUSPENDED
           
static double TRANSITION
           
static int UNINITIALIZED
           
static double WAITING_FOR_FUTURE
           
static double WAITING_FOR_RESOURCE
           
static double WAITING_FOR_SIGNAL
           
static double WORKING
           
 
Constructor Summary
OmarClock()
          Create an OmarClock object.
OmarClock(boolean rt, double rtFactor)
          Create an OmarClock object.
 
Method Summary
 void addThread(java.lang.Thread t)
          Add a new thread to the status Table.
 void cleanoutStatusTable()
          Cleans out the status table.
 void clockThreadSleep(long msecs)
          Clock thread sleep.
static java.lang.String getClockStateString(double state)
          Converts a double representing a clock thread's status into a String.
 java.lang.Double getLastSuspendedTime(java.lang.Thread t)
          Returns the most recent time at which thread t was suspended.
 java.lang.Double getPreviousThreadState(java.lang.Thread t)
          Return the prior state of the Thread as stored in the statusTable
 double getRealTimeFactor()
           
 java.util.HashMap getResourceMap()
          Get a copy of the resourceMap.
 int getStatus()
          Returns the Status of the clock as an integer, derived from the status field.
 java.util.Hashtable getStatusTable()
          Get a copy of the statusTable.
 java.lang.Thread getThread()
          Returns the clock threads Thread object
 java.lang.Double getThreadState(java.lang.Thread t)
          Return the status of the Thread as stored in the statusTable WORKING : Currently executing code WAITING_FOR_SIGNAL : Waiting for a withSignal to match WAITING_FOR_FUTURE : Waiting for a Future to complete WAITING_FOR_RESOURCE : Waiting for a resource to become free SLEEPING : Waiting until a certain simulation time SUSPENDED : Waiting for resource or method conflict to end.
static java.lang.String getThreadStateString(double state)
          Converts a double representing a clock thread's status into a String.
 java.lang.Double getThreadStateUnsafe(java.lang.Thread t)
          Similar to getThreadState(Thread) except that it does not guarantee that the operation will execute atomically.
 double getTime()
          Getter for the time field of the clock.
 void interruptClock()
          interruptClock: If the clock thread is in a Thread.sleep() to advance the time, use this function to cause it to wake early.
 boolean isRealTime()
           
 void killClock()
          Kills the clock and waits for the clock Thread to die.
 boolean lockStatusTable()
          Acquire the semaphore for the status Table
 void pauseClock()
          Pause clock convience function.
 void pauseClock(boolean autoPauseP)
          Pause the clock.
 void printStatusTable()
          Print out the status table to System.out.
 void removeThread(java.lang.Thread t)
          Remove a thread from the status Table.
 void resetClock()
          Resets simulation time to 0.0, interrupts all executing Threads, and clears out the statusTable.
 void resume(java.lang.Thread t)
          Resumes a previosuly suspended thread.
abstract  void run()
          Main run method, called when the clock Thread is started by Scenario.initialize.
 void runClock()
          Continue the clock from the paused state.
 boolean setAcquiredResource(java.lang.Thread t, double state, java.lang.String resource, boolean isAcquired)
          Tells OmarClock the name of the resource that thread t either acquired or released.
 void setRealTime(boolean rt, double rtFactor)
          Set the mode of a clock that has already been created.
 void setThreadState(java.lang.Thread t, double state)
          Sets the status of an executing Thread.
 void setThreadStateUnsafe(java.lang.Thread t, double state)
          Similar to setThreadState(Thread, double) except that it does not guarantee that the operation will execute atomically.
protected  boolean setTime(double time)
          Advance the simulation time.
 boolean setWaitingForResource(java.lang.Thread t, java.lang.String resource)
          Tells OmarClock the name of the resource that thread t is waiting on.
abstract  void sleep(java.lang.Thread t, double sleepTime)
          Sleep method.
 void startClock()
          Start the clock from the Initialized state.
 boolean suspend(java.lang.Thread t)
          Suspends a thread.
 void unlockStatusTable()
          Release the semaphore for the status table
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

UNINITIALIZED

public static final int UNINITIALIZED
See Also:
Constant Field Values

INITIALIZED

public static final int INITIALIZED
See Also:
Constant Field Values

RUNNING

public static final int RUNNING
See Also:
Constant Field Values

PAUSED

public static final int PAUSED
See Also:
Constant Field Values

KILLED

public static final int KILLED
See Also:
Constant Field Values

WORKING

public static final double WORKING
See Also:
Constant Field Values

WAITING_FOR_SIGNAL

public static final double WAITING_FOR_SIGNAL
See Also:
Constant Field Values

WAITING_FOR_FUTURE

public static final double WAITING_FOR_FUTURE
See Also:
Constant Field Values

SUSPENDED

public static final double SUSPENDED
See Also:
Constant Field Values

TRANSITION

public static final double TRANSITION
See Also:
Constant Field Values

WAITING_FOR_RESOURCE

public static final double WAITING_FOR_RESOURCE
See Also:
Constant Field Values

DEAD

public static final double DEAD
See Also:
Constant Field Values

_time

protected double _time

_statusTable

protected java.util.Hashtable _statusTable

_thread

protected java.lang.Thread _thread

_clockSync

protected EDU.oswego.cs.dl.util.concurrent.Semaphore _clockSync

_pausedSync

protected EDU.oswego.cs.dl.util.concurrent.Semaphore _pausedSync

_statusTableSync

protected EDU.oswego.cs.dl.util.concurrent.Mutex _statusTableSync

_stateChangedSync

protected EDU.oswego.cs.dl.util.concurrent.Mutex _stateChangedSync

_isSleepingSync

protected EDU.oswego.cs.dl.util.concurrent.Mutex _isSleepingSync

_realTime

protected boolean _realTime

_realTimeFactor

protected double _realTimeFactor

_zeroTime

protected long _zeroTime

_pauseTime

protected long _pauseTime

_sleeping

protected boolean _sleeping

_sigProc

protected SignalProcessor _sigProc

_resourceMap

protected java.util.HashMap _resourceMap

_status

protected OmarClock.StatusObj _status
Constructor Detail

OmarClock

public OmarClock()
Create an OmarClock object. This should only be called by Scenario.initialize() By default, the clock will be in fast-time mode.


OmarClock

public OmarClock(boolean rt,
                 double rtFactor)
Create an OmarClock object.

Parameters:
rt - true = real-time mode, false = fast-time mode
rtFactor - = one tick of simulation time = 1/rtFactor real-time seconds
Method Detail

setRealTime

public void setRealTime(boolean rt,
                        double rtFactor)
Set the mode of a clock that has already been created. If we change the realTime factor

Parameters:
rt - true = real-time mode, false = fast-time mode
rtFactor - = one tick of simulation time = 1/rtFactor real-time seconds

isRealTime

public boolean isRealTime()

getRealTimeFactor

public double getRealTimeFactor()

run

public abstract void run()
Main run method, called when the clock Thread is started by Scenario.initialize. To be overridden by implementation classes.

Specified by:
run in interface java.lang.Runnable

sleep

public abstract void sleep(java.lang.Thread t,
                           double sleepTime)
Sleep method. To be called by threads that want to sleep for a designated period of time. To be overridden by implementation classes.

Parameters:
t - The thread that wants to sleep.
sleepTime - How long the thread wants to sleep for

pauseClock

public void pauseClock(boolean autoPauseP)
Pause the clock. Dont return until it is paused. The clock will be in the paused state ONLY when all Threads are sleeping or waiting. If a Thread is busy, the clock will only pause when it is done. Thus, an inifinite loop in a Thread will cause pauseClock to never return.


pauseClock

public void pauseClock()
Pause clock convience function. Just does a pauseClock(false).


startClock

public void startClock()
Start the clock from the Initialized state. Waits until the clock is running and paused before returning. This should only be called once to start the clock.


runClock

public void runClock()
Continue the clock from the paused state. Returns immediately.


killClock

public void killClock()
Kills the clock and waits for the clock Thread to die. Also cleans out the statusTable and flushes the SignalProcessor.


setThreadState

public void setThreadState(java.lang.Thread t,
                           double state)
                    throws java.lang.InterruptedException
Sets the status of an executing Thread.

Parameters:
t - Thread object, if it is not in the statusTable, put a new entry for it in.
state - Status of the Thread [WORKING | WAITING_FOR_SIGNAL | WAITING_FOR_FUTURE | WAITING_FOR_RESOURCE | SUSPENDED | TRANSITION | ]
java.lang.InterruptedException

setWaitingForResource

public boolean setWaitingForResource(java.lang.Thread t,
                                     java.lang.String resource)
Tells OmarClock the name of the resource that thread t is waiting on. It also registers the thread in OmarClock if OmarClock isn't aware of it at that time. This method also updates the state of the thread to WAITING_FOR_RESOURCE. This method can be used in place of setThread(Thread t, double state) when state is WAITING_FOR_RESOURCE.

Parameters:
t - The thread
resource - The String resource name that the thread is waiting on
Returns:
true if method succeeds, false if specified resource is null or empty or an exception occurs. It also returns false if the thread currently owns the resource. In this later case, only the state of thread is changed to WAITING_FOR_RESOURCE the resource parameter is ignored.

setAcquiredResource

public boolean setAcquiredResource(java.lang.Thread t,
                                   double state,
                                   java.lang.String resource,
                                   boolean isAcquired)
Tells OmarClock the name of the resource that thread t either acquired or released. It also registers the thread in OmarClock if OmarClock isn't aware of it at that time.

Parameters:
t - The thread
resource - The String resource name that the thread acquired or released.
isAcquired - true if thread acquired resource, false if it released it.
Returns:
true if method succeeds, false if one or more of the conditions holds true:

  • specified resource name is null or of length zero.
  • isAcquired to false and thread t is not one of the currently suspended threads.
  • An Exception occurs.

The method does not do anything if it returns false.


setThreadStateUnsafe

public void setThreadStateUnsafe(java.lang.Thread t,
                                 double state)
Similar to setThreadState(Thread, double) except that it does not guarantee that the operation will execute atomically. Callers should enclose this call within lockStatusTable() and unlockStateTable() calls.

Parameters:
t - Thread object, if it is not in the statusTable, put a new entry for it in.
state - Status of the Thread [WORKING | WAITING_FOR_SIGNAL | WAITING_FOR_FUTURE | WAITING_FOR_RESOURCE | SUSPENDED | TRANSITION | ]

suspend

public boolean suspend(java.lang.Thread t)
Suspends a thread. This call blocks until thread t either sleeps or begins waiting on a signal or begins waiting on a future before suspending it.

Parameters:
t - thread to be suspended
Returns:
true if the thread was successfully suspended, false if thread finished executing before it could be suspended or if some other error occurs.

resume

public void resume(java.lang.Thread t)
Resumes a previosuly suspended thread. If the thread was sleeping at the time of suspension, it is put back to sleep for an amount of time equal to the difference between its scheduled wakeup time and the clock time just before it was suspended.

Parameters:
t - thread to be resumed.

getLastSuspendedTime

public java.lang.Double getLastSuspendedTime(java.lang.Thread t)
Returns the most recent time at which thread t was suspended.

Parameters:
t - thread object.
Returns:
most recent suspension time, null if thread t does not exist, -1 if t was never suspended.

lockStatusTable

public boolean lockStatusTable()
Acquire the semaphore for the status Table


unlockStatusTable

public void unlockStatusTable()
Release the semaphore for the status table


addThread

public void addThread(java.lang.Thread t)
Add a new thread to the status Table. Put it in the WORKING state. This method acquires and releases the statusTable lock.


removeThread

public void removeThread(java.lang.Thread t)
Remove a thread from the status Table. This method acquires and releases the status table lock


interruptClock

public void interruptClock()
interruptClock: If the clock thread is in a Thread.sleep() to advance the time, use this function to cause it to wake early. This is used by the SignalProcessor when an external signal is received. This is because the newly arrived signal may match with a waiting Thread's SignalWait, allowing that thread to continue working.


getTime

public double getTime()
Getter for the time field of the clock.


clockThreadSleep

public void clockThreadSleep(long msecs)
                      throws java.lang.InterruptedException
Clock thread sleep. This method will cause the Clock thread itself to sleep for X milliseconds. Throws the InterruptedException if the sleep was interrupted so that callers can handle it appropriately.

java.lang.InterruptedException

setTime

protected boolean setTime(double time)
Advance the simulation time. If in fast-time mode, this is simply a this.time = time call. If in real-time mode, we calculate how much time has elapsed, and from that how much time we need to sleep for, then do a Thread.sleep. If the Thread.sleep is interrupted, calculate the new currentTime, and return false. If the Thread.sleep completes, set the new time and return true. This method also sends a TIME-UPDATE signal. Perhaps this method should be moved to the implementation classes, since it's not really used for NonSimulationClock.

Parameters:
time - Time to advance to
Returns:
true if time was set successfully, false if we were interrupted

getStatus

public int getStatus()
Returns the Status of the clock as an integer, derived from the status field. The OmarClock can be in one of 5 states:

Returns:
int representing the status of the clock.

getStatusTable

public java.util.Hashtable getStatusTable()
Get a copy of the statusTable. Used by test programs for debug purposes

Returns:
Hashtable a clone of the clock's status table

getResourceMap

public java.util.HashMap getResourceMap()
Get a copy of the resourceMap. Used by test programs for debug purposes

Returns:
HashMap a clone of the resource Map

getThreadState

public java.lang.Double getThreadState(java.lang.Thread t)
Return the status of the Thread as stored in the statusTable A Thread in the SLEEPING state will have it's status set to the time at which it will wake up, which is a double between 0 and infinity.

Returns:
Double representing the thread's status.

getThreadStateUnsafe

public java.lang.Double getThreadStateUnsafe(java.lang.Thread t)
Similar to getThreadState(Thread) except that it does not guarantee that the operation will execute atomically. Callers should enclose this call within lockStatusTable() and unlockStateTable()

Returns:
Double: the status of the Thread as stored in the statusTable

getPreviousThreadState

public java.lang.Double getPreviousThreadState(java.lang.Thread t)
Return the prior state of the Thread as stored in the statusTable

Returns:
Double representing the thread's previous status.

getThread

public java.lang.Thread getThread()
Returns the clock threads Thread object

Returns:
Thread that is executing the run() method of the OmarClock.

getThreadStateString

public static java.lang.String getThreadStateString(double state)
Converts a double representing a clock thread's status into a String.

Returns:
String status

getClockStateString

public static java.lang.String getClockStateString(double state)
Converts a double representing a clock thread's status into a String.

Returns:
String status

cleanoutStatusTable

public void cleanoutStatusTable()
Cleans out the status table.


printStatusTable

public void printStatusTable()
Print out the status table to System.out.


resetClock

public void resetClock()
Resets simulation time to 0.0, interrupts all executing Threads, and clears out the statusTable. Resets the status of the clock to UNINITIALIZED and calls startClock to restart the clock