dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hdsd / scd / fsm / scd_stm_done.cpp
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_done.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_done.cpp
new file mode 100644 (file)
index 0000000..9d54d60
--- /dev/null
@@ -0,0 +1,64 @@
+#include "fsm/scd_stm_done.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_done::set_busy()
+{
+    _fsm.set_state(_st_busy);
+}
+
+
+void scd_stm_done::set_idle(const sc_core::sc_time& time)
+{
+    _time_step = time;
+    _fsm.set_state(_st_idle);
+}
+
+
+void scd_stm_done::process()
+{
+    if (!_check_slaves())
+        return;
+    
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+    bool terminate = true;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+    {
+        if (!(*iter)->idle() && !(*iter)->done())
+        {
+            // this slave is not ready yet
+            return;
+        }
+
+        if (!(*iter)->done())
+            terminate = false;
+    }
+
+    /* all slaves seem idle or done. wait a short moment, to prevent
+     * race conditions (channel data in transit but both endpoints done).
+     * if no socket activity occured we can move on, else we cancel.
+     */
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+        return;
+
+    if (terminate)
+    {
+        // all slaves seem to be done
+        for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+            (*iter)->send_term_req();
+        _fsm.save_state();
+        _fsm.set_state(_st_term_req);
+    }
+    else
+    {
+        // some slaves are not done yet
+        for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+            (*iter)->send_time_req();
+        _fsm.save_state();
+        _fsm.set_state(_st_time_req);
+    }
+}