From: <jsa...@us...> - 2008-10-23 15:51:38
|
Revision: 32 http://flexotask.svn.sourceforge.net/flexotask/?rev=32&view=rev Author: jsauerbach Date: 2008-10-23 15:51:28 +0000 (Thu, 23 Oct 2008) Log Message: ----------- Fix various bugs that caused the new flexotask-functiontest to crash or misbehave. Modified Paths: -------------- trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskGraphImpl.java trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskThreadFactoryImpl.java trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskValidator.java Modified: trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskGraphImpl.java =================================================================== --- trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskGraphImpl.java 2008-10-23 15:49:07 UTC (rev 31) +++ trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskGraphImpl.java 2008-10-23 15:51:28 UTC (rev 32) @@ -41,6 +41,9 @@ /** The objects that were pinned to run this graph */ private Object[] pinned; + + /** The classes that were marked stable in this graph */ + private Class[] stable; /** * Non-public constructor @@ -48,17 +51,18 @@ * @param guards a map from task names to guards for all atomic Flexotasks in the graph * @param pinned objects that were pinned to run this graph */ - FlexotaskGraphImpl(FlexotaskDistributer distributer, Map guards, Object[] pinned) + FlexotaskGraphImpl(FlexotaskDistributer distributer, Map guards, Object[] pinned, Class[] stable) { this.distributer = distributer; this.guards = guards; this.pinned = pinned; + this.stable = stable; FlexotaskSystemSupport.checkSecurity(this, "FlexotaskGraph"); distributer.instantiated(); } /** - * Destroy the FlexotaskTemplate and free all of its resources + * Destroy the FlexotaskGraph and free all of its resources */ public void destroy() { @@ -71,15 +75,28 @@ this.runner = null; } runner.shutdown(); - distributer.destroyed(); + if (distributer != null) { + distributer.destroyed(); + } distributer = null; - exception = null; for (Iterator iterator = guards.values().iterator(); iterator.hasNext();) { AtomicFlexotaskGuard guard = (AtomicFlexotaskGuard) iterator.next(); guard.setDelegate(null); } - FlexotaskObjectPinner.unpinObjects(pinned); + if (pinned != null) { + FlexotaskObjectPinner.unpinObjects(pinned); + } pinned = null; + /* The following is probably temporary, implying that graphs using stable/transient cannot run + * concurrently, which is the case in the underlying VM at the moment. + */ + if (stable != null) { + for (int i = 0; i < stable.length; i++) { + FlexotaskSystemSupport.setStable(stable[i], false); + } + } + stable = null; + FlexotaskSystemSupport.setTransientPolicy(false); // TODO add code to recover memory spaces belonging to FlexotaskControllers } @@ -103,7 +120,7 @@ } /** - * Get the FlexotaskRunner for this FlexotaskTemplate. An FlexotaskRunner controls the + * Get the FlexotaskRunner for this FlexotaskGraph. An FlexotaskRunner controls the * execution of the graph to the extent the scheduler grants such control * @return the runner supplied by the FlexotaskScheduler */ Modified: trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskThreadFactoryImpl.java =================================================================== --- trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskThreadFactoryImpl.java 2008-10-23 15:49:07 UTC (rev 31) +++ trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskThreadFactoryImpl.java 2008-10-23 15:51:28 UTC (rev 32) @@ -67,7 +67,7 @@ /* Ensure this method is called at most once per graph lifetime */ if (threadsCreated) { throw new IllegalStateException("Flexotask scheduler attempted to create more than one set " + - "of threads for an FlexotaskTemplate"); + "of threads for a FlexotaskGraph"); } threadsCreated = true; tracerFactory.startThreadCreation(); @@ -139,7 +139,7 @@ * Make a new SchedulerWrapper * @param target the actual scheduler runnable to be wrapped by this wrapper * @param threadContext the context object to use for tracing - * @param graph the FlexotaskTemplate of which this thread is a member + * @param graph the FlexotaskGraph of which this thread is a member */ SchedulerWrapper(Runnable target, ThreadContext threadContext, FlexotaskGraphImpl graph) { @@ -161,8 +161,11 @@ } finally { FlexotaskSystemSupport.becomeFlexotaskThread(false); FlexotaskSystemSupport.runOnPublicHeap(); + if (t != null) { + t = (Throwable) FlexotaskSystemSupport.deepClone(t, null); + } + graph.destroy(); graph.setException(t); - graph.destroy(); //System.err.println("!!!Scheduler thread terminated!!!"); if (t == null) { //System.err.println("Apparently, termination was normal"); Modified: trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskValidator.java =================================================================== --- trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskValidator.java 2008-10-23 15:49:07 UTC (rev 31) +++ trunk/flexotask/src/com/ibm/realtime/flexotask/system/FlexotaskValidator.java 2008-10-23 15:51:28 UTC (rev 32) @@ -22,7 +22,6 @@ import java.util.Map; import java.util.Set; -import com.ibm.realtime.flexotask.AtomicException; import com.ibm.realtime.flexotask.AtomicFlexotask; import com.ibm.realtime.flexotask.Flexotask; import com.ibm.realtime.flexotask.FlexotaskGraph; @@ -38,7 +37,6 @@ import com.ibm.realtime.flexotask.distribution.FlexotaskTimerService; import com.ibm.realtime.flexotask.scheduling.ConnectionDriver; import com.ibm.realtime.flexotask.scheduling.FlexotaskController; -import com.ibm.realtime.flexotask.scheduling.FlexotaskPredicateController; import com.ibm.realtime.flexotask.scheduling.FlexotaskScheduler; import com.ibm.realtime.flexotask.scheduling.FlexotaskSchedulerRegistry; import com.ibm.realtime.flexotask.scheduling.FlexotaskSchedulingData; @@ -54,6 +52,7 @@ import com.ibm.realtime.flexotask.tracing.FlexotaskTaskTracer; import com.ibm.realtime.flexotask.tracing.FlexotaskTracer; import com.ibm.realtime.flexotask.tracing.FlexotaskTracerFactory; +import com.ibm.realtime.flexotask.util.NanoTime; import com.ibm.realtime.flexotask.validation.AtomicFlexotaskGuard; import com.ibm.realtime.flexotask.vm.FlexotaskRoot; import com.ibm.realtime.flexotask.vm.FlexotaskVMBridge; @@ -71,27 +70,35 @@ /** The classloader to be used to resolve classes needed by the validator */ private static ClassLoader cl = ClassLoader.getSystemClassLoader(); - /* The following ensures that all classes whose instances are used invariably during the - * "flexotask heap" phase of task instantiation are fully initialized, including the assignment of - * their name strings. Otherwise, their name strings could end up allocated in the Flexotask heap. + /* The following ensures that all classes that might have been overlooked by the + * validator during its validation phase because they are part of the system and not + * the application but that might end up being used indirectly by the application are + * also fully initialized. This does not include classes that are used by schedulers, + * tracers: for now, schedulers and tracers are responsible for making their own classes + * live. + * Important: after changing the set of classes that might be involved in this issuse this + * list must be udated! + * TODO this procedure is very fragile ... let's try to do something better. */ static { - /* Invariant classes */ - FlexotaskCommunicator.class.getName(); - FlexotaskChannel.class.getName(); - FlexotaskCommunicatorTemplate.class.getName(); - FlexotaskController.class.getName(); - FlexotaskInputPort.class.getName(); + FlexotaskRoot.class.getName(); FlexotaskInputPort[].class.getName(); - FlexotaskOutputPort.class.getName(); + FlexotaskInputPortImpl.class.getName(); FlexotaskOutputPort[].class.getName(); - FlexotaskPredicateController.class.getName(); - FlexotaskPredicateTemplate.class.getName(); + FlexotaskOutputPortImpl.class.getName(); + Flexotask.class.getName(); FlexotaskValidationException.class.getName(); - FlexotaskRoot.class.getName(); + AtomicFlexotask.class.getName(); TransactionalOperations.class.getName(); - AtomicException.class.getName(); - ExecutionAbortedException.class.getName(); + TimeAware.class.getName(); + PortBuffer.class.getName(); + FlexotaskTracer.class.getName(); + FlexotaskTaskTracer.class.getName(); + FlexotaskTracer.NullTracer.class.getName(); + FlexotaskPredicateTemplate.class.getName(); + FlexotaskController.class.getName(); + FlexotaskControllerImpl.class.getName(); + NanoTime.class.getName(); } /** @@ -196,6 +203,8 @@ /* Pin any objects that must be pinned. */ verbosePinObjects(toPin, "heap objects found during validation"); + /* Transfer stable/transient information to runtime */ + Class[] stable = initStableTransient(specification); /* Instantiate the graph */ tracerFactory.startInstantiation(); Map instantiationMap; @@ -235,7 +244,7 @@ toPin = allPinned; } /* Create the graph */ - FlexotaskGraphImpl ans = new FlexotaskGraphImpl(distributer, guards, toPin); + FlexotaskGraphImpl ans = new FlexotaskGraphImpl(distributer, guards, toPin, stable); /* Schedule the graph */ tracerFactory.startScheduling(); FlexotaskThreadFactory factory = new FlexotaskThreadFactoryImpl(timer, tracerFactory, ans); @@ -266,7 +275,7 @@ } /** - * Check an FlexotaskTemplate for internal consistency. A consistent specification + * Check a FlexotaskTemplate for internal consistency. A consistent specification * is one that would be valid if all the code of all the Flexotasks proves to be valid. * <p>The following consistency rules are enforced (bear in mind that graph inputs and * outputs and communicators are also tasks at this level). @@ -432,9 +441,6 @@ private static Map instantiate(FlexotaskTemplate specification, Map heapSizes, Map initializationMap, FlexotaskTimer timer) throws FlexotaskValidationException { - /* Transfer stable/transient information to runtime */ - initStableTransient(specification); - Map byRefConnMap = new HashMap(); /** Map the between task name and a list of the names of its output ports that are by-reference */ for (Iterator iter = specification.getConnections().iterator(); iter.hasNext();) { @@ -488,23 +494,36 @@ /** * Initialize the stable/transient information in the runtime * @param template the template to use for this information + * @return the array of stable classes for recovery at termination or null if the default + * policy is used * @throws FlexotaskValidationException * @throws ClassNotFoundException */ - private static void initStableTransient(FlexotaskTemplate template) throws FlexotaskValidationException + private static Class[] initStableTransient(FlexotaskTemplate template) throws FlexotaskValidationException { if (template.getStableMode() == FlexotaskStableMode.DEFAULT) { - return; + FlexotaskSystemSupport.setTransientPolicy(false); + return null; } Set stableClasses = template.getStableClasses(); + Class[] ans = new Class[stableClasses.size()]; try { + int index = 0; for (Iterator iterator = stableClasses.iterator(); iterator.hasNext();) { - FlexotaskSystemSupport.setStable(CodeValidator.resolveClass((String) iterator.next(), cl), true); + Class aClass = CodeValidator.resolveClass((String) iterator.next(), cl); + FlexotaskSystemSupport.setStable(aClass, true); + ans[index++] = aClass; } } catch (ClassNotFoundException e) { + for (int i = 0; i < ans.length; i++) { + if (ans[i] != null) { + FlexotaskSystemSupport.setStable(ans[i], false); + } + } throw new FlexotaskValidationException("Could not find declared stable class: " + e.getMessage()); } FlexotaskSystemSupport.setTransientPolicy(true); + return ans; } /** @@ -641,22 +660,28 @@ * location. Restore the memory space before doing the collect so that the collect isn't * confused with a synchronous GC. */ + flexotask = null; // Kill this: it is unsafe to use after GC! FlexotaskSystemSupport.runOnPublicHeap(); //System.err.println("About to garbage collect initial heap of " + task.getName()); FlexotaskSystemSupport.collectHeap(root); + //System.err.println("Collected " + task.getName()); /* Create the proper kind of controller for this task. */ FlexotaskTaskTracer tracer = tracerFactory.newTaskTracer(task.getName()); + //System.err.println("Created tracer for " + task.getName()); if (task instanceof FlexotaskPredicateTemplate) { return new FlexotaskPredicateControllerImpl(root, task.getName(), tracer); - } else if (flexotask instanceof AtomicFlexotask){ + } + //System.err.println("Testing for AtomicFlexotask: " + task.getName()); + if (root.getTask() instanceof AtomicFlexotask) { + /* Call root.getTask() ... don't use flexotask variable from before because the object + * may have moved! */ return new AtomicFlexotaskController(root, task.getName(), tracer); - } - else { + } else { return new FlexotaskControllerImpl(root, task.getName(), tracer); } } finally { /* TODO: clean up for errors that occur after memory space has been created but before - * instantiation is complete. But, to do this, we also need a clean FlexotaskTemplate + * instantiation is complete. But, to do this, we also need a clean FlexotaskGraph * tear-down story, even for the normal case, which is not yet in place. */ FlexotaskSystemSupport.runOnPublicHeap(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |