|
@@ -11,11 +11,11 @@
|
|
|
self.taskname = taskname
|
|
|
self.mvs_operations = mvs_operations
|
|
|
self.mvk = mvk
|
|
|
+ self.unlocked = True
|
|
|
|
|
|
- self.failed = False
|
|
|
+ self.input_queue = []
|
|
|
self.output_queue = []
|
|
|
self.outputs = []
|
|
|
- self.do_yield = False
|
|
|
]]>
|
|
|
</body>
|
|
|
|
|
@@ -37,91 +37,27 @@
|
|
|
if commands is None:
|
|
|
break
|
|
|
reply = [mvs_operations[command[0]](*(command[1])) for command in commands]
|
|
|
+ return (0.0, False)
|
|
|
+ except SleepKernel as e:
|
|
|
+ print("Got sleep for: " + str(e.timeout))
|
|
|
+ return (e.timeout, False)
|
|
|
except:
|
|
|
import traceback
|
|
|
print(traceback.format_exc())
|
|
|
- #TODO delete self, as the task has crashed!
|
|
|
- return False
|
|
|
- return True
|
|
|
+ return (float('inf'), False)
|
|
|
]]>
|
|
|
</body>
|
|
|
</method>
|
|
|
|
|
|
- <scxml initial="start">
|
|
|
- <parallel id="start">
|
|
|
- <state id="execution" initial="running">
|
|
|
- <state id="running" initial="executing">
|
|
|
- <transition event="pause_task" target="../suspended"/>
|
|
|
-
|
|
|
- <state id="executing">
|
|
|
- <onentry>
|
|
|
- <script>
|
|
|
- start_time = time.time()
|
|
|
- # Grant each task some milliseconds of execution
|
|
|
- self.do_yield = False
|
|
|
- while (time.time() - start_time < 0.05):
|
|
|
- if not self.execute_modelverse(self.taskname, "execute_rule", []):
|
|
|
- # Failed!
|
|
|
- self.failed = True
|
|
|
- break
|
|
|
-
|
|
|
- if not self.mvk.success:
|
|
|
- # Blocking or broken, so quit already to stop wasting CPU
|
|
|
- self.do_yield = True
|
|
|
- break
|
|
|
-
|
|
|
- if not self.failed:
|
|
|
- # Perform output if there is anything
|
|
|
- while self.output_queue:
|
|
|
- if self.execute_modelverse(self.taskname, "get_output", []):
|
|
|
- if self.mvk.success:
|
|
|
- self.outputs.append((self.output_queue.pop(0), self.mvk.returnvalue))
|
|
|
- else:
|
|
|
- # No output left in Mv, so break
|
|
|
- break
|
|
|
- else:
|
|
|
- self.failed = True
|
|
|
- break
|
|
|
- </script>
|
|
|
- </onentry>
|
|
|
-
|
|
|
- <transition cond="self.failed" target="../../failed"/>
|
|
|
- <transition after="self.sccd_yield()" target="."/>
|
|
|
- <transition cond="self.do_yield" target="../yielded"/>
|
|
|
- </state>
|
|
|
-
|
|
|
- <state id="yielded">
|
|
|
- <transition after="self.sccd_yield() + 1" target="../executing"/>
|
|
|
- <transition event="processed_input" target="../executing"/>
|
|
|
- <transition event="waiting_output" target="../executing"/>
|
|
|
- </state>
|
|
|
- </state>
|
|
|
-
|
|
|
- <state id="suspended">
|
|
|
- <state id="suspended">
|
|
|
- <transition event="resume" target="../../running"/>
|
|
|
- </state>
|
|
|
- </state>
|
|
|
-
|
|
|
- <state id="failed">
|
|
|
- <state id="failed">
|
|
|
- <!-- TODO delete task -->
|
|
|
- </state>
|
|
|
- </state>
|
|
|
- </state>
|
|
|
-
|
|
|
- <state id="process_events">
|
|
|
- <state id="process_events">
|
|
|
+ <scxml initial="main">
|
|
|
+ <parallel id="main">
|
|
|
+ <state id="queue">
|
|
|
+ <state id="queue">
|
|
|
<transition event="input" target=".">
|
|
|
<parameter name="params"/>
|
|
|
<script>
|
|
|
- for args_entry in params:
|
|
|
- if not self.execute_modelverse(self.taskname, "set_input", [args_entry]):
|
|
|
- # Failed!
|
|
|
- self.failed = True
|
|
|
- break
|
|
|
+ self.input_queue.extend(params)
|
|
|
</script>
|
|
|
- <raise event="processed_input"/>
|
|
|
</transition>
|
|
|
|
|
|
<transition event="output" target=".">
|
|
@@ -129,7 +65,6 @@
|
|
|
<script>
|
|
|
self.output_queue.append(params)
|
|
|
</script>
|
|
|
- <raise event="waiting_output"/>
|
|
|
</transition>
|
|
|
|
|
|
<transition cond="self.outputs" target=".">
|
|
@@ -142,6 +77,107 @@
|
|
|
</transition>
|
|
|
</state>
|
|
|
</state>
|
|
|
+
|
|
|
+ <state id="process" initial="running">
|
|
|
+ <state id="running" initial="components">
|
|
|
+ <transition event="suspend" target="../suspended"/>
|
|
|
+
|
|
|
+ <history id="history" type="deep"/>
|
|
|
+
|
|
|
+ <parallel id="components">
|
|
|
+ <state id="input">
|
|
|
+ <state id="input">
|
|
|
+ <transition cond="self.input_queue" target=".">
|
|
|
+ <script>
|
|
|
+ for args_entry in self.input_queue:
|
|
|
+ self.execute_modelverse(self.taskname, "set_input", [args_entry])
|
|
|
+ self.input_queue = []
|
|
|
+ </script>
|
|
|
+ <raise event="wake_timer"/>
|
|
|
+ </transition>
|
|
|
+ </state>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="processing" initial="processing">
|
|
|
+ <state id="processing">
|
|
|
+ <onentry>
|
|
|
+ <script>
|
|
|
+ start_time = time.time()
|
|
|
+ # Grant each task some milliseconds of execution
|
|
|
+ while (time.time() - start_time < 0.05):
|
|
|
+ timeout = self.execute_modelverse(self.taskname, "execute_rule", [])
|
|
|
+ if timeout[0] > 0.0:
|
|
|
+ # We should not continue immediately
|
|
|
+ break
|
|
|
+ self.timeout = timeout
|
|
|
+ </script>
|
|
|
+ </onentry>
|
|
|
+
|
|
|
+ <transition cond="self.timeout[0] == 0.0" after="self.sccd_yield()" target="."/>
|
|
|
+ <transition cond="0.0 < self.timeout[0] < float('inf')" after="self.sccd_yield()" target="../blocked">
|
|
|
+ <script>
|
|
|
+ self.unlocked = False
|
|
|
+ </script>
|
|
|
+ <raise event="start_timer">
|
|
|
+ <parameter expr="self.timeout[0]"/>
|
|
|
+ <parameter expr="self.timeout[1]"/>
|
|
|
+ </raise>
|
|
|
+ </transition>
|
|
|
+ <transition cond="self.timeout[0] == float('inf')" target="../failed"/>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="blocked">
|
|
|
+ <transition cond="self.unlocked" target="../processing"/>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="failed">
|
|
|
+ <script>
|
|
|
+ print("TODO: task has failed")
|
|
|
+ </script>
|
|
|
+ </state>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="output">
|
|
|
+ <state id="output">
|
|
|
+ <onentry>
|
|
|
+ <script>
|
|
|
+ if self.output_queue:
|
|
|
+ if self.execute_modelverse(self.taskname, "get_output", []):
|
|
|
+ self.outputs.append((self.output_queue.pop(0), self.mvk.returnvalue))
|
|
|
+ </script>
|
|
|
+ </onentry>
|
|
|
+ </state>
|
|
|
+ </state>
|
|
|
+ </parallel>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="suspended">
|
|
|
+ <transition event="resume" target="../running/history"/>
|
|
|
+ </state>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="timer" initial="ready">
|
|
|
+ <state id="waiting">
|
|
|
+ <transition after="self.sccd_yield() + self.timer_duration" target="../ready"/>
|
|
|
+ <transition event="wake_timer" cond="self.interruptable" target="../ready"/>
|
|
|
+ </state>
|
|
|
+
|
|
|
+ <state id="ready">
|
|
|
+ <onentry>
|
|
|
+ <script>
|
|
|
+ self.unlocked = True
|
|
|
+ </script>
|
|
|
+ </onentry>
|
|
|
+ <transition event="start_timer" target="../waiting">
|
|
|
+ <parameter name="duration"/>
|
|
|
+ <parameter name="interruptable"/>
|
|
|
+ <script>
|
|
|
+ self.timer_duration = duration
|
|
|
+ self.interruptable = interruptable
|
|
|
+ </script>
|
|
|
+ </transition>
|
|
|
+ </state>
|
|
|
+ </state>
|
|
|
</parallel>
|
|
|
</scxml>
|
|
|
</class>
|