systemc: Don't depend on the order of static initializers.

STL containers may need to be constructed before they're used. Don't
count on being able to insert into them during a static initializer.

Change-Id: Icb05d5084a470e1ebd976ae6e1954b1a78aabd6a
Reviewed-on: https://gem5-review.googlesource.com/c/13329
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2018-10-07 03:59:56 -07:00
parent b366cbcde9
commit 3420f0e223
4 changed files with 69 additions and 12 deletions

View File

@@ -40,14 +40,25 @@ namespace sc_gem5
namespace
{
std::vector<PythonReadyFunc *> pythonReadyFuncs;
std::vector<PythonInitFunc *> pythonInitFuncs;
PythonReadyFunc *&
firstReadyFunc()
{
static PythonReadyFunc *first = nullptr;
return first;
}
PythonInitFunc *&
firstInitFunc()
{
static PythonInitFunc *first = nullptr;
return first;
}
void
python_ready(pybind11::args args)
{
for (auto &func: pythonReadyFuncs)
func->run();
for (auto ptr = firstReadyFunc(); ptr; ptr = ptr->next)
ptr->run();
}
void
@@ -55,21 +66,21 @@ systemc_pybind(pybind11::module &m_internal)
{
pybind11::module m = m_internal.def_submodule("systemc");
m.def("python_ready", &python_ready);
for (auto &func: pythonInitFuncs)
func->run(m);
for (auto ptr = firstInitFunc(); ptr; ptr = ptr->next)
ptr->run(m);
}
EmbeddedPyBind embed_("systemc", &systemc_pybind);
} // anonymous namespace
PythonReadyFunc::PythonReadyFunc()
PythonReadyFunc::PythonReadyFunc() : next(firstReadyFunc())
{
pythonReadyFuncs.push_back(this);
firstReadyFunc() = this;
}
PythonInitFunc::PythonInitFunc()
PythonInitFunc::PythonInitFunc() : next(firstInitFunc())
{
pythonInitFuncs.push_back(this);
firstInitFunc() = this;
}
} // namespace sc_gem5

View File

@@ -37,6 +37,8 @@ namespace sc_gem5
struct PythonReadyFunc
{
PythonReadyFunc *next;
PythonReadyFunc();
~PythonReadyFunc() {}
virtual void run() = 0;
@@ -44,6 +46,8 @@ struct PythonReadyFunc
struct PythonInitFunc
{
PythonInitFunc *next;
PythonInitFunc();
~PythonInitFunc() {}
virtual void run(pybind11::module &systemc) = 0;

View File

@@ -29,6 +29,8 @@
#include "systemc/utils/report.hh"
#include "systemc/core/python.hh"
namespace sc_gem5
{
@@ -63,11 +65,42 @@ std::unique_ptr<sc_core::sc_report> globalReportCache;
bool reportWarningsAsErrors = false;
DefaultReportMessages::DefaultReportMessages(
std::initializer_list<std::pair<int, const char *>> msgs)
DefaultReportMessages *&
DefaultReportMessages::top()
{
static DefaultReportMessages *top_ptr = nullptr;
return top_ptr;
}
void
DefaultReportMessages::install()
{
for (auto &p: msgs)
sc_core::sc_report::register_id(p.first, p.second);
}
DefaultReportMessages::DefaultReportMessages(
std::initializer_list<std::pair<int, const char *>> msgs) :
next(top()), msgs(msgs)
{
top() = this;
}
void
DefaultReportMessages::installAll()
{
for (DefaultReportMessages *ptr = top(); ptr; ptr = ptr->next)
ptr->install();
}
namespace
{
struct InstallDefaultReportMessages : public PythonReadyFunc
{
void run() override { DefaultReportMessages::installAll(); }
} messageInstaller;
} // anonymous namespace
} // namespace sc_gem5

View File

@@ -110,8 +110,17 @@ extern bool reportWarningsAsErrors;
struct DefaultReportMessages
{
protected:
static DefaultReportMessages *&top();
DefaultReportMessages *next;
std::initializer_list<std::pair<int, const char *>> msgs;
void install();
public:
DefaultReportMessages(std::initializer_list<std::pair<int, const char *>>);
static void installAll();
};
} // namespace sc_gem5