systemc: Keep track of how sc_main completes and expose that to python.
authorGabe Black <gabeblack@google.com>
Thu, 23 Aug 2018 03:31:27 +0000 (20:31 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 25 Sep 2018 23:57:52 +0000 (23:57 +0000)
That makes it possible for the config script to retrieve the result of
running sc_main. sc_main (or at least the python front end for it)
can't return results directly since it usually doesn't run to
completion when it's first called.

Change-Id: I9740e9688571e2ca824a684be70480f1eadddcdb
Reviewed-on: https://gem5-review.googlesource.com/12253
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/systemc/core/SystemC.py
src/systemc/core/sc_main.cc

index 13ef4eb9810d2caf1a9d3ecd767dba5e860edce5..49b569b0c77ac7f86a84077d317c6b92c1b79341 100644 (file)
@@ -36,11 +36,22 @@ class SystemC_Kernel(SimObject):
     cxx_class = 'sc_gem5::Kernel'
     cxx_header = 'systemc/core/kernel.hh'
 
+    class ScMainResult(object):
+        def __init__(self, code, message):
+            self.code = code
+            self.message = message
+
     def sc_main(self, *args):
         '''Call the systemc sc_main function with the given string args'''
         from _m5.systemc import sc_main
         sc_main(*args)
 
+    def sc_main_result(self):
+        '''Retrieve and return the results of running sc_main'''
+        from _m5.systemc import sc_main_result_code, sc_main_result_str
+        return SystemC_Kernel.ScMainResult(
+                sc_main_result_code(), sc_main_result_str());
+
 # This class represents systemc sc_object instances in python config files. It
 # inherits from SimObject in python, but the c++ version, sc_core::sc_object,
 # doesn't inherit from gem5's c++ SimObject class.
index bacde2e0f77cec1affd5356172f0949e3fab7e0b..47ca2e3544ecb5e06b74ceb42bd998833cb658c1 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <cstring>
+#include <string>
 
 #include "base/fiber.hh"
 #include "base/logging.hh"
@@ -57,13 +58,28 @@ char **_argv = NULL;
 
 class ScMainFiber : public Fiber
 {
+  public:
+    std::string resultStr;
+    int resultInt;
+
+    ScMainFiber() : resultInt(1) {}
+
     void
     main()
     {
         if (::sc_main) {
-            ::sc_main(_argc, _argv);
-            // Make sure no systemc events/notifications are scheduled
-            // after sc_main returns.
+            try {
+                resultInt = ::sc_main(_argc, _argv);
+                if (resultInt)
+                    resultStr = "sc_main returned non-zero";
+                else
+                    resultStr = "sc_main finished";
+                // Make sure no systemc events/notifications are scheduled
+                // after sc_main returns.
+            } catch (const sc_report &r) {
+                // There was an exception nobody caught.
+                resultStr = r.what();
+            }
             ::sc_gem5::Kernel::scMainFinished(true);
             ::sc_gem5::scheduler.clear();
         } else {
@@ -115,6 +131,18 @@ sc_main(pybind11::args args)
     scMainFiber.run();
 }
 
+int
+sc_main_result_code()
+{
+    return scMainFiber.resultInt;
+}
+
+std::string
+sc_main_result_str()
+{
+    return scMainFiber.resultStr;
+}
+
 // Make our sc_main wrapper available in the internal _m5 python module under
 // the systemc submodule.
 
@@ -124,6 +152,8 @@ struct InstallScMain : public ::sc_gem5::PythonInitFunc
     run(pybind11::module &systemc) override
     {
         systemc.def("sc_main", &sc_main);
+        systemc.def("sc_main_result_code", &sc_main_result_code);
+        systemc.def("sc_main_result_str", &sc_main_result_str);
     }
 } installScMain;