/** Report that the manager state has changed. This is called by the manager. */ public void managerStateChanged(Manager manager) { Manager.State newState = manager.getState(); if (newState != _previousState) { report(manager.getState().getDescription()); _previousState = newState; } }
/** * React to the fact that execution is finished by unregistering as an execution listener and by * allowing subsequent executions. This is called when an execution of the referenced model in * another thread has finished and the wrapup sequence has completed normally. The number of * successfully completed iterations can be obtained by calling getIterationCount() on the * manager. * * @param manager The manager controlling the execution. */ public synchronized void executionFinished(Manager manager) { // _executing = false; // NOTE: Can't remove these now! The list is being // currently used to notify me! // manager.removeExecutionListener(this); manager.removeDebugListener(this); notifyAll(); }
/** * Compile the given model with the given name. This method invokes other methods of this class to * actually perform the compilation. */ public void compile(String modelName, CompositeActor toplevel, GeneratorAttribute attribute) throws Exception { // try { long startTime = System.currentTimeMillis(); // Create instance classes for the actors. try { initialize(toplevel); } catch (Throwable ex) { System.out.println("initialize() failed: " + ex); } if (attribute.getParameter("outputDirectory").indexOf(" ") != -1) { throw new Exception( "The outputDirectory contains one or more " + "spaces. Unfortunately, the Soot option passing " + "mechanism does not handle spaces. The value of " + "the outputDirectory parameter was: \"" + attribute.getParameter("outputDirectory") + "\""); } // Parse any copernicus args. String[] sootArgs = _parseArgs(attribute); if (sootArgs == null) { throw new NullPointerException( "Failed to parse args for " + attribute + ", resulting arg array was null"); } // Add Transforms to the Scene. addTransforms(); // Execute the transforms. generateCode(sootArgs); // Reset the state of the manager. We haven't actually done // anything, but the state of the manager must be reset. try { _toplevel.getManager().wrapup(); } catch (Exception exception) { // This could be a problem with NonStrictTest. throw new KernelRuntimeException(exception, "Could not wrapup composite actor"); } // Print out memory usage info System.out.println(modelName + " " + ptolemy.actor.Manager.timeAndMemory(startTime)); // } catch (Exception ex) { // System.err.println("Code generation of '" + modelName // + "' failed:"); // // ex.printStackTrace(System.err); // // System.err.flush(); // // System.exit(2); // } }
/** * React to the fact that execution has failed by unregistering as an execution listener and by * allowing subsequent executions. Report an execution failure at the next opportunity. This * method will be called when an exception or error is caught by a manager during a run in another * thread of the referenced model. * * @param manager The manager controlling the execution. * @param throwable The throwable to report. */ public synchronized void executionError(Manager manager, Throwable throwable) { _throwable = throwable; // _executing = false; // NOTE: Can't remove these now! The list is being // currently used to notify me! // manager.removeExecutionListener(this); manager.removeDebugListener(this); notifyAll(); }
/** * Read in a MoML class, sanitize the top level name, initialize the model. Usually initialize() * is called after calling readInModel(). * * <p>If the director is an SDF director, then the number of iterations is handled specially. If * the director is an SDF director and a parameter called "copernicus_iterations" is present, then * the value of that parameter is used as the number of iterations. If the director is an SDF * director, and there is no "copernicus_iterations" parameter but the * "ptolemy.ptII.copernicusIterations" Java property is set, then the value of that property is * used as the number of iterations. * * @param toplevel The model we are generating code for. */ public void initialize(CompositeActor toplevel) throws IllegalActionException, NameDuplicationException { _toplevel = toplevel; // Applet codegen works with all directors, not just SDF. Director topLevelDirector = toplevel.getDirector(); // FIXME: nearly duplicate code in java/TestApplication.java if (topLevelDirector != null && topLevelDirector instanceof SDFDirector) { SDFDirector director = (SDFDirector) topLevelDirector; Parameter iterations = (Parameter) director.getAttribute("iterations"); Parameter copernicus_iterations = (Parameter) director.getAttribute("copernicus_iterations"); // Set to be a large number of iterations, unless // copernicus_iterations is set. if (copernicus_iterations != null) { iterations.setToken(copernicus_iterations.getToken()); } else { String copernicusIterations = StringUtilities.getProperty("ptolemy.ptII.copernicusIterations"); if (copernicusIterations.length() > 0) { System.out.println( "KernelMain: " + "Setting number of iterations to " + copernicusIterations); iterations.setToken(new IntToken(copernicusIterations)); } } } // Initialize the model to ensure type resolution and scheduling // are done. try { Manager manager = new Manager(_toplevel.workspace(), "manager"); _toplevel.setManager(manager); manager.preinitializeAndResolveTypes(); } catch (Exception exception) { throw new KernelRuntimeException(exception, "Could not initialize composite actor"); } }
/** * Put a token on the queue contained in this receiver. If the queue is full, then suspend the * calling thread (blocking write) and inform the director of the same. Resume the process on * detecting room in the queue. If a termination is requested, then initiate the termination of * the calling process by throwing a TerminateProcessException. On detecting a room in the queue, * put a token in the queue. Check whether any process is blocked on a read from this receiver. If * a process is indeed blocked, then unblock the process, and inform the director of the same. * * @param token The token to be put in the receiver, or null to not put anything. * @exception NoRoomException If during initialization, capacity cannot be increased enough to * accommodate initial tokens. */ public void put(Token token) throws NoRoomException { IOPort port = getContainer(); if (port == null || token == null) { return; // Nothing to do. } Workspace workspace = port.workspace(); while (!_terminate) { int depth = 0; try { // NOTE: Avoid acquiring read access on the workspace // while holding the lock on the director because if // some other process is trying to acquire write access, // the request for read access will be deferred. Nameable container = getContainer().getContainer(); Manager manager = ((Actor) container).getManager(); // NOTE: This used to synchronize on this, but since it calls // director methods that are synchronized on the director, // this can cause deadlock. synchronized (_director) { // Need to check this again after acquiring the lock. // Otherwise, could end up calling wait() below _after_ // notification has occurred. if (_terminate) { break; } // If we are in the initialization phase, then we may have // to increase the queue capacity before proceeding. This // may be needed to support PublisherPorts that produce // initial tokens (or, I suppose, any actor that produces // initial tokens during initialize()?). if (!super.hasRoom()) { if (container instanceof Actor) { if (manager.getState().equals(Manager.INITIALIZING)) { try { _queue.setCapacity(_queue.getCapacity() + 1); } catch (IllegalActionException e) { throw new NoRoomException( getContainer(), "Failed to increase queue capacity enough to accommodate initial tokens"); } } } } // Try to write. if (super.hasRoom()) { super.put(token); // If any thread is blocked on a get(), then it will become // unblocked. Notify the director now so that there isn't a // spurious deadlock detection. if (_readPending != null) { _director.threadUnblocked(_readPending, this, PNDirector.READ_BLOCKED); _readPending = null; } // Normally, the _writePending reference will have // been cleared by the read that unblocked this write. // However, it might be that the director increased the // buffer size, which would also have the affect of unblocking // this write. Hence, we clear it here if it is set. if (_writePending != null) { _director.threadUnblocked(_writePending, this, PNDirector.WRITE_BLOCKED); _writePending = null; } break; } // Wait to try again. _writePending = Thread.currentThread(); _director.threadBlocked(_writePending, this, PNDirector.WRITE_BLOCKED); // NOTE: We cannot use workspace.wait(Object) here without // introducing a race condition, because we have to release // the lock on the _director before calling workspace.wait(_director). depth = workspace.releaseReadPermission(); _director.wait(); } // release lock on _director before reacquiring read permissions. } catch (InterruptedException e) { _terminate = true; } finally { if (depth > 0) { workspace.reacquireReadPermission(depth); } } } if (_terminate) { throw new TerminateProcessException("Process terminated."); } }
/** * Report in debugging statements that the manager state has changed. This method is called if the * referenced model is executed in another thread and the manager changes state. * * @param manager The manager controlling the execution. * @see Manager#getState() */ public void managerStateChanged(Manager manager) { if (_debugging) { _debug("Referenced model manager state: " + manager.getState()); } }
/** * Parse the xml file and run it. If a parameter named "copernicus_iterations" is present, then * the value of that parameter is used to set the iterations parameter. If there is no * "copernicus_iterations" parameter, then then the number of iterations is set to 100000. */ public TestApplication(String xmlFilename) throws Exception { MoMLParser parser = new MoMLParser(); // The test suite calls MoMLSimpleApplication multiple times, // and the list of filters is static, so we reset it each time // so as to avoid adding filters every time we run an auto test. // We set the list of MoMLFilters to handle Backward Compatibility. MoMLParser.setMoMLFilters(BackwardCompatibility.allFilters()); // Filter out any graphical classes. // We should filter out graphical classes or the // treeShakeWithoutCodegen rule will fail when we run it on // actor/lib/test/auto/ComplexDivide. MoMLParser.addMoMLFilter(new RemoveGraphicalClasses()); // parser.setErrorHandler(new StreamErrorHandler()); // We use parse(URL, URL) here instead of parseFile(String) // because parseFile() works best on relative pathnames and // has problems finding resources like files specified in // parameters if the xml file was specified as an absolute path. CompositeActor toplevel = null; // First, we gc and then print the memory stats // BTW to get more info about gc, // use java -verbose:gc -Xloggc:filename . . . System.gc(); Thread.sleep(1000); Runtime runtime = Runtime.getRuntime(); try { URL url = new URL(null, xmlFilename); toplevel = (CompositeActor) parser.parse(url, url.openStream()); } catch (Exception ex) { File f = new File(xmlFilename); URL url = f.toURL(); System.err.println("Warning: Parsing '" + xmlFilename + "' failed: "); ex.printStackTrace(); System.err.println(" Trying '" + url + "'"); toplevel = (CompositeActor) parser.parse(null, url); } // FIXME: nearly duplicate code in kernel/KernelMain.java SDFDirector director = (SDFDirector) toplevel.getDirector(); if (director != null) { Parameter iterations = (Parameter) director.getAttribute("iterations"); Parameter copernicus_iterations = (Parameter) director.getAttribute("copernicus_iterations"); // Set to be a large number of iterations, unless // copernicus_iterations is set. if (copernicus_iterations != null) { iterations.setToken(copernicus_iterations.getToken()); } else { iterations.setToken(new IntToken(100000)); } System.out.println("TestApplication: Setting Iterations to " + iterations.getToken()); } Manager manager = new Manager(toplevel.workspace(), "TestApplication"); toplevel.setManager(manager); toplevel.addChangeListener(this); String modelName = toplevel.getName(); long startTime = System.currentTimeMillis(); long totalMemory1 = runtime.totalMemory() / 1024; long freeMemory1 = runtime.freeMemory() / 1024; System.out.println("Spent " + (startTime - _parseStartTime) + " ms. creating the model."); System.out.println( modelName + ": Stats before execution: " + Manager.timeAndMemory(startTime, totalMemory1, freeMemory1)); // Second, we run and print memory stats. manager.execute(); long totalMemory2 = runtime.totalMemory() / 1024; long freeMemory2 = runtime.freeMemory() / 1024; String standardStats = Manager.timeAndMemory(startTime, totalMemory2, freeMemory2); System.out.println(modelName + ": Execution stats: " + standardStats); // Third, we gc and print memory stats. System.gc(); Thread.sleep(1000); long totalMemory3 = runtime.totalMemory() / 1024; long freeMemory3 = runtime.freeMemory() / 1024; System.out.println( modelName + ": After Garbage Collection: " + Manager.timeAndMemory(startTime, totalMemory3, freeMemory3)); // Print out the standard stats at the end // so as not to break too many scripts System.out.println(standardStats); }