/* SCCS - @(#)NslMultiClockScheduler.java 1.4 - 02/22/99 - 14:29:33 */
// Copyright: Copyright (c) 1997 University of Southern California Brain Project.
// Copyright: This software may be freely copied provided the toplevel
// Copyright: COPYRIGHT file is included with each such copy.
// Copyright: Email nsl@java.usc.edu.
/*
* $Log: NslMultiClockScheduler.java,v $
* Revision 1.4 1997/11/18 01:18:18 erhan
* *** empty log message ***
*
* Revision 1.3 1997/11/06 03:15:28 erhan
* nsl3.0.b
*
* Revision 1.2 1997/07/30 21:19:44 erhan
* nsl3.0
*
* Revision 1.1.1.1 1997/03/12 22:52:21 nsl
* new dir structure
*
* Revision 1.1.1.1 1997/02/08 00:40:40 nsl
* Imported the Source directory
*
*/
//
// NslMultiClockScheduler.java
//
//////////////////////////////////////////////////////////////////////
/**
* NslMultiClockScheduler - a multi-clocked scheduler.
In NslMultiClockScheduler, each module can have its
run_step_size, or each has different run time
interval. In the currnt implementation, the run_step_size
must be set by setRunStepSize in makeinst
in NslModule. Otherwise, the module will have system
default time step and in order to activate this parameter,
the whole model has to be removed from the scheduler and
re-initialize.
The run step size of each module should be the maximum possible
step size without making chaotic behaviour in the model.
Run step size of modules without execution part, like top-level
modules, should be 0. This could improve the performance of
simulation
* @see NslModule#setRunStepSize, NslModule#getRunStepSize
*/
package nslj.src.system;
import nslj.src.lang.NslModule;
import nslj.src.display.*;
import java.lang.*;
import java.util.Vector;
import java.util.Enumeration;
public class NslMultiClockScheduler extends NslScheduler {
Vector clock_list; // a list of vectors, in which contains
// modules with a same run time step size
Vector moduleList;
NslSystem system;
// it keep checking the minimum run step size in the module.
// it is used to warn the system the possibility that the
// system run step size is larger than the required run step
// size.
double _min_step_size=Double.MAX_VALUE;
public NslMultiClockScheduler(NslSystem sys) {
system = sys;
simulationSuspended = true;
moduleList = new Vector(10,10);
clock_list = new Vector(10,10);
}
/**
* Add module into the scheduler.
* If there exists a list of
* modules with the same run step size as the object module,
* the module will be added to the corresponding list.
* Otherwise, a list of module with that run step size will be created.
* There is no maximum number of those lists, but keeping it
* minimal can significantly speed up the simulation.
* @param module - module to be added.
*
*/
void addSorted(NslClockSchedulerModuleVector V, NslModule m) {
int pos;
NslModule first,second;
Enumeration E = V.elements(); //the different loops
// empty: insert wherever
if (V.size()==0) {
V.addElement(m);
return;
}
first = (NslModule)E.nextElement(); pos=0;
// insert at front
if ((first.getorder_str()).compareTo(m.getorder_str()) >= 0 ) {
V.insertElementAt(m,pos);
return;
}
// insert between two modules
while(E.hasMoreElements()) {
second = (NslModule)E.nextElement(); pos++;
if ((first.getorder_str()).compareTo(m.getorder_str()) <= 0 )
if ((second.getorder_str()).compareTo(m.getorder_str()) >= 0 ) {
V.insertElementAt(m,pos);
return;
}
first=second;
}
// insert at the end
V.addElement(m);
}
public void createSchedulerList() {
/*clock_list = new Vector(10,10);
Enumeration e = moduleList.elements();
while (e.hasMoreElements()) {
addModuleToClockList((NslModule)e.nextElement());
}*/
}
public void addModuleToClockList(NslModule module) {
/* TOD0: change from comparing string lenght to actually looking at
the system.schedulerMethod string.
*/
System.out.println("Adding module "+module.getName()+" with delta "+
module.getRunStepSize());
NslModule d;
if(module==null)
throw new NullPointerException();
Enumeration E = clock_list.elements();
NslClockSchedulerModuleVector V;
double stepsize = module.getRunStepSize();
while (E.hasMoreElements()) {
V = (NslClockSchedulerModuleVector)E.nextElement();
if(V.getRunStepSize() == stepsize) {
addSorted(V,module); // V.addElement(module);
return;
}
}
// no module vector or step size is new
if (stepsize>0 && stepsize < _min_step_size) {
_min_step_size = stepsize;
system.setRunStepSize(stepsize);
}
V = new NslClockSchedulerModuleVector(stepsize);
addSorted(V,module); // V.addElement(module);
clock_list.addElement(V);
return;
}
public void addModule(NslModule module) {
//moduleList.addElement(module);
addModuleToClockList(module);
}
/**
* Do nothing.
* @param link - link to be added.
*/
public void addConnection(/*NslConnection link*/) {}
/**
* Run the active modules until the NslSystem.end_time
*/
public void run() {
run(system.getRunEndTime());
}
/**
* Run the active modules until time time
in the basic step size specified in NslSystem
The modules registered in the scheduler will run
with an interval specified by the run step size.
* @param time - end time for running
*/
public void run(double end_time) {
double dt = system.getRunStepSize();
contEndTime=actualEndTime=originalEndTime=end_time;
NslDisplaySystemVector dsv = system.display_system_list;
Enumeration E = clock_list.elements();
NslClockSchedulerModuleVector V;
while (E.hasMoreElements()) {
V = (NslClockSchedulerModuleVector)E.nextElement();
V.init_run();
}
// scheduler
for (; ;) {
try {
//System.out.println(getClass().getName()+": Waiting for message");
synchronized (this) {
while (simulationSuspended || system.train_or_run!='R')
wait();
if (actualEndTimecontEndTime)
wait();
if (actualEndTime