/* 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