Source('sc_interface.cc')
Source('sc_join.cc')
Source('sc_main.cc')
+ Source('sc_main_fiber.cc')
Source('sc_module.cc')
Source('sc_module_name.cc')
Source('sc_object.cc')
#include "systemc/core/channel.hh"
#include "systemc/core/module.hh"
#include "systemc/core/port.hh"
+#include "systemc/core/sc_main_fiber.hh"
#include "systemc/core/scheduler.hh"
namespace sc_gem5
namespace
{
-bool scMainDone = false;
bool stopAfterCallbacks = false;
bool startComplete = false;
bool endComplete = false;
bool Kernel::startOfSimulationComplete() { return startComplete; }
bool Kernel::endOfSimulationComplete() { return endComplete; }
-bool Kernel::scMainFinished() { return scMainDone; }
-void Kernel::scMainFinished(bool finished) { scMainDone = finished; }
-
sc_core::sc_status Kernel::status() { return _status; }
void Kernel::status(sc_core::sc_status s) { _status = s; }
void
Kernel::init()
{
- if (scMainDone)
+ if (scMainFiber.finished())
return;
if (stopAfterCallbacks)
void
Kernel::regStats()
{
- if (scMainDone || stopAfterCallbacks)
+ if (scMainFiber.finished() || stopAfterCallbacks)
return;
try {
void
Kernel::startup()
{
- if (scMainDone)
+ if (scMainFiber.finished())
return;
schedule(t0Event, curTick());
static bool startOfSimulationComplete();
static bool endOfSimulationComplete();
- static bool scMainFinished();
- static void scMainFinished(bool);
-
private:
static void stopWork();
#include "sim/init.hh"
#include "systemc/core/kernel.hh"
#include "systemc/core/python.hh"
+#include "systemc/core/sc_main_fiber.hh"
#include "systemc/core/scheduler.hh"
#include "systemc/ext/core/messages.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/utils/sc_report_handler.hh"
#include "systemc/utils/report.hh"
-// A weak symbol to detect if sc_main has been defined, and if so where it is.
-[[gnu::weak]] int sc_main(int argc, char *argv[]);
-
namespace sc_core
{
namespace
{
-bool scMainCalled = false;
-
-int _argc = 0;
-char **_argv = NULL;
-
-class ScMainFiber : public Fiber
-{
- public:
- std::string resultStr;
- int resultInt;
-
- ScMainFiber() : resultInt(1) {}
-
- void
- main()
- {
- if (::sc_main) {
- 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 = "uncaught sc_report";
- sc_gem5::reportHandlerProc(
- r, sc_report_handler::get_catch_actions());
- } catch (...) {
- // There was some other type of exception we need to wrap.
- resultStr = "uncaught exception";
- sc_gem5::reportHandlerProc(
- ::sc_gem5::reportifyException(),
- sc_report_handler::get_catch_actions());
- }
- ::sc_gem5::Kernel::scMainFinished(true);
- ::sc_gem5::scheduler.clear();
- } else {
- // If python tries to call sc_main but no sc_main was defined...
- fatal("sc_main called but not defined.\n");
- }
- }
-};
-
-ScMainFiber scMainFiber;
-
// This wrapper adapts the python version of sc_main to the c++ version.
void
sc_main(pybind11::args args)
{
- panic_if(scMainCalled, "sc_main called more than once.");
+ panic_if(::sc_gem5::scMainFiber.called(),
+ "sc_main called more than once.");
- _argc = args.size();
- _argv = new char *[_argc];
+ int argc = args.size();
+ char **argv = new char *[argc];
- // Initialize all the _argvs to NULL so we can delete [] them
+ // Initialize all the argvs to NULL so we can delete [] them
// unconditionally.
- for (int idx = 0; idx < _argc; idx++)
- _argv[idx] = NULL;
+ for (int idx = 0; idx < argc; idx++)
+ argv[idx] = NULL;
// Attempt to convert all the arguments to strings. If that fails, clean
// up after ourselves. Also don't count this as a call to sc_main since
// we never got to the c++ version of that function.
try {
- for (int idx = 0; idx < _argc; idx++) {
+ for (int idx = 0; idx < argc; idx++) {
std::string arg = args[idx].cast<std::string>();
- _argv[idx] = new char[arg.length() + 1];
- strcpy(_argv[idx], arg.c_str());
+ argv[idx] = new char[arg.length() + 1];
+ strcpy(argv[idx], arg.c_str());
}
} catch (...) {
// If that didn't work for some reason (probably a conversion error)
- // blow away _argv and _argc and pass on the exception.
- for (int idx = 0; idx < _argc; idx++)
- delete [] _argv[idx];
- delete [] _argv;
- _argc = 0;
+ // blow away argv and argc and pass on the exception.
+ for (int idx = 0; idx < argc; idx++)
+ delete [] argv[idx];
+ delete [] argv;
+ argc = 0;
throw;
}
- // At this point we're going to call the c++ sc_main, so we can't try
- // again later.
- scMainCalled = true;
-
- scMainFiber.run();
+ ::sc_gem5::scMainFiber.setArgs(argc, argv);
+ ::sc_gem5::scMainFiber.run();
}
int
sc_main_result_code()
{
- return scMainFiber.resultInt;
+ return ::sc_gem5::scMainFiber.resultInt();
}
std::string
sc_main_result_str()
{
- return scMainFiber.resultStr;
+ return ::sc_gem5::scMainFiber.resultStr();
}
// Make our sc_main wrapper available in the internal _m5 python module under
int
sc_argc()
{
- return _argc;
+ return ::sc_gem5::scMainFiber.argc();
}
const char *const *
sc_argv()
{
- return _argv;
+ return ::sc_gem5::scMainFiber.argv();
}
void
--- /dev/null
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "systemc/core/sc_main_fiber.hh"
+
+#include <cstring>
+#include <string>
+
+#include "systemc/core/kernel.hh"
+#include "systemc/core/scheduler.hh"
+#include "systemc/ext/core/messages.hh"
+#include "systemc/ext/core/sc_main.hh"
+#include "systemc/ext/utils/sc_report_handler.hh"
+#include "systemc/utils/report.hh"
+
+// A weak symbol to detect if sc_main has been defined, and if so where it is.
+[[gnu::weak]] int sc_main(int argc, char *argv[]);
+
+namespace sc_gem5
+{
+
+void
+ScMainFiber::main()
+{
+ _called = true;
+
+ if (::sc_main) {
+ 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_core::sc_report &r) {
+ // There was an exception nobody caught.
+ _resultStr = "uncaught sc_report";
+ reportHandlerProc(
+ r, ::sc_core::sc_report_handler::get_catch_actions());
+ } catch (...) {
+ // There was some other type of exception we need to wrap.
+ _resultStr = "uncaught exception";
+ reportHandlerProc(reportifyException(),
+ ::sc_core::sc_report_handler::get_catch_actions());
+ }
+ scheduler.clear();
+ } else {
+ // If python tries to call sc_main but no sc_main was defined...
+ fatal("sc_main called but not defined.\n");
+ }
+}
+
+ScMainFiber scMainFiber;
+
+} // namespace sc_gem5
--- /dev/null
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __SYSTEMC_CORE_SC_MAIN_FIBER_HH__
+#define __SYSTEMC_CORE_SC_MAIN_FIBER_HH__
+
+#include "base/fiber.hh"
+#include "base/logging.hh"
+
+namespace sc_gem5
+{
+
+class ScMainFiber : public Fiber
+{
+ private:
+ int _argc = 0;
+ char **_argv = NULL;
+ std::string _resultStr;
+ int _resultInt = 1;
+
+ bool _called = false;
+
+ public:
+ int argc() { return _argc; }
+ const char *const *argv() { return _argv; }
+ std::string resultStr() { return _resultStr; }
+ int resultInt() { return _resultInt; }
+ bool called() { return _called; }
+
+ void
+ setArgs(int new_argc, char **new_argv)
+ {
+ _argc = new_argc;
+ _argv = new_argv;
+ }
+
+ void main() override;
+};
+
+extern ScMainFiber scMainFiber;
+
+} // namespace sc_gem5
+
+#endif // __SYSTEMC_CORE_SC_MAIN_FIBER_HH__
#include "base/logging.hh"
#include "sim/eventq.hh"
#include "systemc/core/kernel.hh"
+#include "systemc/core/sc_main_fiber.hh"
#include "systemc/ext/core/messages.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/utils/sc_report.hh"
Scheduler::Scheduler() :
eq(nullptr), readyEvent(this, false, ReadyPriority),
pauseEvent(this, false, PausePriority),
- stopEvent(this, false, StopPriority),
- scMain(nullptr), _throwToScMain(nullptr),
+ stopEvent(this, false, StopPriority), _throwToScMain(nullptr),
starvationEvent(this, false, StarvationPriority),
_elaborationDone(false), _started(false), _stopNow(false),
_status(StatusOther), maxTickEvent(this, false, MaxTickPriority),
status(StatusPaused);
kernel->status(::sc_core::SC_PAUSED);
runOnce = false;
- if (scMain && !scMain->finished())
- scMain->run();
+ if (scMainFiber.called() && !scMainFiber.finished())
+ scMainFiber.run();
}
void
clear();
runOnce = false;
- if (scMain && !scMain->finished())
- scMain->run();
+ if (scMainFiber.called() && !scMainFiber.finished())
+ scMainFiber.run();
}
void
Scheduler::start(Tick max_tick, bool run_to_time)
{
- // We should be running from sc_main. Keep track of that Fiber to return
- // to later.
- scMain = Fiber::currentFiber();
-
_started = true;
status(StatusOther);
runToTime = run_to_time;
::sc_core::sc_report report = reportifyException();
_throwToScMain = &report;
status(StatusOther);
- scMain->run();
+ scMainFiber.run();
}
void
// Run delta events.
void runDelta();
- void setScMainFiber(Fiber *sc_main) { scMain = sc_main; }
-
void start(Tick max_tick, bool run_to_time);
void oneCycle();
EventWrapper<Scheduler, &Scheduler::pause> pauseEvent;
EventWrapper<Scheduler, &Scheduler::stop> stopEvent;
- Fiber *scMain;
const ::sc_core::sc_report *_throwToScMain;
bool