From 163eb3c56b115e649c72fceff89c8370b6e7306f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Sep 2018 17:12:46 -0700 Subject: systemc: Centralize how object parents are chosen. There's a lot of repeated code for this. Also, the sc_vector type needs to be able to artificially inject a parent for the objects it creates. Change-Id: I76f9b551632cd2cd70e26741b215290b35c382e9 Reviewed-on: https://gem5-review.googlesource.com/c/13194 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/core/module.cc | 100 +++++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 36 deletions(-) (limited to 'src/systemc/core/module.cc') diff --git a/src/systemc/core/module.cc b/src/systemc/core/module.cc index afc3bf241..f342b7f05 100644 --- a/src/systemc/core/module.cc +++ b/src/systemc/core/module.cc @@ -45,8 +45,6 @@ namespace std::list _modules; Module *_new_module; -Module *_callbackModule = nullptr; - } // anonymous namespace Module::Module(const char *name) : @@ -59,10 +57,15 @@ Module::Module(const char *name) : Module::~Module() { - if (_new_module == this) { - // Aborted module construction? + // Aborted module construction? + if (_new_module == this) _new_module = nullptr; - } + + // Attempt to pop now in case we're at the top of the stack, so that + // a stale pointer to us isn't left floating around for somebody to trip + // on. + pop(); + allModules.remove(this); } @@ -72,21 +75,29 @@ Module::finish(Object *this_obj) assert(!_obj); _obj = this_obj; _modules.push_back(this); - _new_module = nullptr; - // This is called from the constructor of this_obj, so it can't use - // dynamic cast. - sc_mod(static_cast<::sc_core::sc_module *>(this_obj->sc_obj())); - allModules.emplace_back(this); + pushParentModule(this); + try { + _new_module = nullptr; + // This is called from the constructor of this_obj, so it can't use + // dynamic cast. + sc_mod(static_cast<::sc_core::sc_module *>(this_obj->sc_obj())); + allModules.emplace_back(this); + } catch (...) { + popParentModule(); + throw; + } } void Module::pop() { - panic_if(!_modules.size(), "Popping from empty module list.\n"); - panic_if(_modules.back() != this, - "Popping module which isn't at the end of the module list.\n"); + if (_modules.empty() || _modules.back() != this) + return; + panic_if(_new_module, "Pop with unfinished module.\n"); + _modules.pop_back(); + popParentModule(); } void @@ -111,11 +122,16 @@ Module::bindPorts(std::vector &proxies) void Module::beforeEndOfElaboration() { - callbackModule(this); - _sc_mod->before_end_of_elaboration(); - for (auto e: exports) - e->before_end_of_elaboration(); - callbackModule(nullptr); + pushParentModule(this); + try { + _sc_mod->before_end_of_elaboration(); + for (auto e: exports) + e->before_end_of_elaboration(); + } catch (...) { + popParentModule(); + throw; + } + popParentModule(); } void @@ -127,31 +143,46 @@ Module::endOfElaboration() "did you forget to add a sc_module_name parameter to " "your module constructor?", msg.c_str()); } - callbackModule(this); - _sc_mod->end_of_elaboration(); - for (auto e: exports) - e->end_of_elaboration(); - callbackModule(nullptr); + pushParentModule(this); + try { + _sc_mod->end_of_elaboration(); + for (auto e: exports) + e->end_of_elaboration(); + } catch (...) { + popParentModule(); + throw; + } + popParentModule(); } void Module::startOfSimulation() { - callbackModule(this); - _sc_mod->start_of_simulation(); - for (auto e: exports) - e->start_of_simulation(); - callbackModule(nullptr); + pushParentModule(this); + try { + _sc_mod->start_of_simulation(); + for (auto e: exports) + e->start_of_simulation(); + } catch (...) { + popParentModule(); + throw; + } + popParentModule(); } void Module::endOfSimulation() { - callbackModule(this); - _sc_mod->end_of_simulation(); - for (auto e: exports) - e->end_of_simulation(); - callbackModule(nullptr); + pushParentModule(this); + try { + _sc_mod->end_of_simulation(); + for (auto e: exports) + e->end_of_simulation(); + } catch(...) { + popParentModule(); + throw; + } + popParentModule(); } Module * @@ -179,9 +210,6 @@ newModule() return _new_module; } -void callbackModule(Module *m) { _callbackModule = m; } -Module *callbackModule() { return _callbackModule; } - std::list allModules; } // namespace sc_gem5 -- cgit v1.2.3