From 9bd3bb7bc804a16b2f0de03fa6d3d9d0928f38a2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 22 Jun 2018 14:19:44 -0700 Subject: systemc: Implement most of sc_object. To avoid making it hard to change sc_object's implementation in the future, this change keeps most of the data members out of sc_object and keeps them in a seperate Object which is managed independently but still matches to the sc_objects one to one. This change also moves away from the SystemC/sc_gem5 namespace pair in favor of sc_gem5. Having two namespaces with classes, etc, living in both was complicating things. Having to use a namespace that doesn't fit in one scheme or the other isn't great, but it's the lesser of two evils. Change-Id: Ib59c3c515ca98c7fe519c59e9fe9270304b71cc0 Reviewed-on: https://gem5-review.googlesource.com/11611 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/core/SConscript | 1 + src/systemc/core/module.cc | 37 ++++-- src/systemc/core/module.hh | 45 +++++-- src/systemc/core/object.cc | 236 +++++++++++++++++++++++++++++++++++++ src/systemc/core/object.hh | 103 ++++++++++++++++ src/systemc/core/sc_module_name.cc | 6 +- src/systemc/core/sc_object.cc | 85 ++++++------- src/systemc/ext/core/sc_object.hh | 16 ++- 8 files changed, 454 insertions(+), 75 deletions(-) create mode 100644 src/systemc/core/object.cc create mode 100644 src/systemc/core/object.hh diff --git a/src/systemc/core/SConscript b/src/systemc/core/SConscript index 2cf410eae..a07c02683 100644 --- a/src/systemc/core/SConscript +++ b/src/systemc/core/SConscript @@ -32,6 +32,7 @@ if env['USE_SYSTEMC']: Source('kernel.cc') Source('module.cc') + Source('object.cc') Source('sc_attr.cc') Source('sc_event.cc') diff --git a/src/systemc/core/module.cc b/src/systemc/core/module.cc index 97a4a9ffa..3b7e922e3 100644 --- a/src/systemc/core/module.cc +++ b/src/systemc/core/module.cc @@ -29,42 +29,59 @@ #include "systemc/core/module.hh" +#include #include #include "base/logging.hh" -namespace SystemC +namespace sc_gem5 { namespace { std::list _modules; - -Module *_top_module = nullptr; +Module *_new_module; } // anonymous namespace +Module::Module(const char *name) : _name(name), _sc_mod(nullptr), _obj(nullptr) +{ + panic_if(_new_module, "Previous module not finished.\n"); + _new_module = this; +} + void -Module::push() +Module::finish(Object *this_obj) { - if (!_top_module) - _top_module = this; + assert(!_obj); + _obj = this_obj; _modules.push_back(this); + _new_module = nullptr; } void Module::pop() { - panic_if(_modules.size(), "Popping from empty module list.\n"); + 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"); + panic_if(_new_module, "Pop with unfinished module.\n"); + _modules.pop_back(); +} + +Module * +currentModule() +{ + if (_modules.empty()) + return nullptr; + return _modules.back(); } Module * -topModule() +newModule() { - return _top_module; + return _new_module; } -} // namespace SystemC +} // namespace sc_gem5 diff --git a/src/systemc/core/module.hh b/src/systemc/core/module.hh index 56e125ee6..3734e633f 100644 --- a/src/systemc/core/module.hh +++ b/src/systemc/core/module.hh @@ -30,31 +30,54 @@ #ifndef __SYSTEMC_CORE_MODULE_HH__ #define __SYSTEMC_CORE_MODULE_HH__ -namespace SystemC +#include + +#include "systemc/core/object.hh" +#include "systemc/ext/core/sc_module.hh" + +namespace sc_gem5 { class Module { private: const char *_name; + sc_core::sc_module *_sc_mod; + Object *_obj; public: - Module(const char *name) : _name(name) {} - const char *name() { return _name; } + Module(const char *name); + void finish(Object *this_obj); - void push(); - void pop(); -}; + const char *name() const { return _name; } -extern Module *topModule(); + sc_core::sc_module * + sc_mod() const + { + assert(_sc_mod); + return _sc_mod; + } -} // namespace SystemC + void + sc_mod(sc_core::sc_module *sc_mod) + { + assert(!_sc_mod); + _sc_mod = sc_mod; + } -namespace sc_gem5 -{ + Object * + obj() + { + assert(_obj); + return _obj; + } + + void pop(); +}; -using SystemC::Module; +Module *currentModule(); +Module *newModule(); } // namespace sc_gem5 diff --git a/src/systemc/core/object.cc b/src/systemc/core/object.cc new file mode 100644 index 000000000..8d2b73545 --- /dev/null +++ b/src/systemc/core/object.cc @@ -0,0 +1,236 @@ +/* + * 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/object.hh" + +#include "base/logging.hh" +#include "systemc/core/module.hh" + +namespace sc_gem5 +{ + +namespace +{ + +ObjectsIt +findObjectIn(Objects &objects, const std::string &name) +{ + ObjectsIt it; + for (it = objects.begin(); it != objects.end(); it++) + if (!strcmp((*it)->name(), name.c_str())) + break; + + return it; +} + +void +addObject(Objects *objects, sc_core::sc_object *object) +{ + objects->emplace(objects->end(), object); +} + +void +popObject(Objects *objects, const std::string &name) +{ + ObjectsIt it = findObjectIn(*objects, name); + assert(it != objects->end()); + std::swap(objects->back(), *it); + objects->pop_back(); +} + +} // anonymous namespace + +Object::Object(sc_core::sc_object *sc_obj) : Object(sc_obj, "object") {} + +Object::Object(sc_core::sc_object *sc_obj, const char *obj_name) : + sc_obj(sc_obj), _basename(obj_name), parent(nullptr) +{ + if (_basename == "") + _basename = "object"; + + Module *p = currentModule(); + + Module *n = newModule(); + if (n) { + // We are a module in the process of being constructed. + n->finish(this); + } + + if (p) { + // We're "within" a parent module, ie we're being created while its + // constructor is running. + parent = p->obj()->sc_obj; + addObject(&parent->_gem5_object->children, sc_obj); + } else if (false /* TODO Check if a process is running */) { + // The process is our parent. + } else { + // We're a top level object. + addObject(&topLevelObjects, sc_obj); + } + + addObject(&allObjects, sc_obj); + + _name = _basename; + sc_core::sc_object *sc_p = parent; + while (sc_p) { + _name = std::string(sc_p->basename()) + std::string(".") + _name; + sc_p = get_parent_object(); + } +} + +Object::Object(sc_core::sc_object *sc_obj, const Object &arg) : + Object(sc_obj, arg._basename.c_str()) +{} + +Object & +Object::operator = (const Object &) +{ + return *this; +} + +Object::~Object() +{ + panic_if(!children.empty(), "Parent object still has children.\n"); + + if (parent) + popObject(&parent->_gem5_object->children, _name); + else + popObject(&topLevelObjects, _name); + popObject(&allObjects, _name); +} + +const char * +Object::name() const +{ + return _name.c_str(); +} + +const char * +Object::basename() const +{ + return _basename.c_str(); +} + +void +Object::print(std::ostream &out) const +{ + out << name(); +} + +void +Object::dump(std::ostream &out) const +{ + out << "name = " << name() << "\n"; + out << "kind = " << sc_obj->kind() << "\n"; +} + +const std::vector & +Object::get_child_objects() const +{ + return children; +} + +const std::vector & +Object::get_child_events() const +{ + return events; +} + +sc_core::sc_object *Object::get_parent_object() const +{ + return parent; +} + +bool +Object::add_attribute(sc_core::sc_attr_base &attr) +{ + return cltn.push_back(&attr); +} + +sc_core::sc_attr_base * +Object::get_attribute(const std::string &attr) +{ + return cltn[attr]; +} + +sc_core::sc_attr_base * +Object::remove_attribute(const std::string &attr) +{ + return cltn.remove(attr); +} + +void +Object::remove_all_attributes() +{ + cltn.remove_all(); +} + +int +Object::num_attributes() const +{ + return cltn.size(); +} + +sc_core::sc_attr_cltn & +Object::attr_cltn() +{ + return cltn; +} + +const sc_core::sc_attr_cltn & +Object::attr_cltn() const +{ + return cltn; +} + +sc_core::sc_simcontext * +Object::simcontext() const +{ + warn("%s not implemented.\n", __PRETTY_FUNCTION__); + return nullptr; +} + + +Objects topLevelObjects; +Objects allObjects; + +const std::vector & +getTopLevelScObjects() +{ + return topLevelObjects; +} + +sc_core::sc_object * +findObject(const char *name, const Objects &objects) +{ + ObjectsIt it = findObjectIn(allObjects, name); + return it == allObjects.end() ? nullptr : *it; +} + +} // namespace sc_gem5 diff --git a/src/systemc/core/object.hh b/src/systemc/core/object.hh new file mode 100644 index 000000000..93c5e8f7c --- /dev/null +++ b/src/systemc/core/object.hh @@ -0,0 +1,103 @@ +/* + * 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_OBJECT_HH__ +#define __SYSTEMC_CORE_OBJECT_HH__ + +#include +#include + +#include "systemc/ext/core/sc_attr.hh" +#include "systemc/ext/core/sc_object.hh" + +namespace sc_gem5 +{ + +class Object; + +typedef std::vector Objects; +typedef std::vector Events; +typedef Objects::iterator ObjectsIt; + +class Object +{ + public: + Object(sc_core::sc_object *sc_obj); + Object(sc_core::sc_object *sc_obj, const char *); + Object(sc_core::sc_object *sc_obj, const Object &); + Object &operator = (const Object &); + + virtual ~Object(); + + /* + * sc_object methods. + */ + const char *name() const; + const char *basename() const; + + void print(std::ostream & =std::cout) const; + void dump(std::ostream & =std::cout) const; + + const std::vector &get_child_objects() const; + const std::vector &get_child_events() const; + sc_core::sc_object *get_parent_object() const; + + bool add_attribute(sc_core::sc_attr_base &); + sc_core::sc_attr_base *get_attribute(const std::string &); + sc_core::sc_attr_base *remove_attribute(const std::string &); + void remove_all_attributes(); + int num_attributes() const; + sc_core::sc_attr_cltn &attr_cltn(); + const sc_core::sc_attr_cltn &attr_cltn() const; + + sc_core::sc_simcontext *simcontext() const; + + private: + sc_core::sc_object *sc_obj; + + std::string _basename; + std::string _name; + + Objects children; + Events events; + sc_core::sc_object *parent; + ObjectsIt parentIt; + + sc_core::sc_attr_cltn cltn; +}; + +extern Objects topLevelObjects; +extern Objects allObjects; + +sc_core::sc_object *findObject( + const char *name, const Objects &objects=topLevelObjects); + +} // namespace sc_gem5 + +#endif //__SYSTEMC_CORE_OBJECT_HH__ diff --git a/src/systemc/core/sc_module_name.cc b/src/systemc/core/sc_module_name.cc index b55e50001..ca568e2ad 100644 --- a/src/systemc/core/sc_module_name.cc +++ b/src/systemc/core/sc_module_name.cc @@ -36,10 +36,8 @@ namespace sc_core { sc_module_name::sc_module_name(const char *name) : - _name(name), _gem5_module(new SystemC::Module(name)), _on_the_stack(true) -{ - _gem5_module->push(); -} + _name(name), _gem5_module(new sc_gem5::Module(name)), _on_the_stack(true) +{} sc_module_name::sc_module_name(const sc_module_name &other) : _name(other._name), _gem5_module(other._gem5_module), _on_the_stack(false) diff --git a/src/systemc/core/sc_object.cc b/src/systemc/core/sc_object.cc index b6883443a..c2e27610b 100644 --- a/src/systemc/core/sc_object.cc +++ b/src/systemc/core/sc_object.cc @@ -27,158 +27,149 @@ * Authors: Gabe Black */ +#include + #include "base/logging.hh" +#include "systemc/core/object.hh" #include "systemc/ext/core/sc_object.hh" namespace sc_core { -const char * -sc_object::name() const +namespace { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return "sc_object"; -} + +std::vector top_level_objects; + +} // anonymous namespace const char * -sc_object::basename() const +sc_object::name() const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return "sc_object"; + return _gem5_object->name(); } const char * -sc_object::kind() const +sc_object::basename() const { - return "sc_object"; + return _gem5_object->basename(); } void sc_object::print(std::ostream &out) const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _gem5_object->print(out); } void sc_object::dump(std::ostream &out) const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _gem5_object->dump(out); } const std::vector & sc_object::get_child_objects() const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return *(const std::vector *)nullptr; + return _gem5_object->get_child_objects(); } const std::vector & sc_object::get_child_events() const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return *(const std::vector *)nullptr; + return _gem5_object->get_child_events(); } sc_object * sc_object::get_parent_object() const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return NULL; + return _gem5_object->get_parent_object(); } bool -sc_object::add_attribute(sc_attr_base &) +sc_object::add_attribute(sc_attr_base &attr) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return false; + return _gem5_object->add_attribute(attr); } sc_attr_base * -sc_object::get_attribute(const std::string &) +sc_object::get_attribute(const std::string &name) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return NULL; + return _gem5_object->get_attribute(name); } sc_attr_base * -sc_object::remove_attribute(const std::string &) +sc_object::remove_attribute(const std::string &name) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return NULL; + return _gem5_object->remove_attribute(name); } void sc_object::remove_all_attributes() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + return _gem5_object->remove_all_attributes(); } int sc_object::num_attributes() const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0; + return _gem5_object->num_attributes(); } sc_attr_cltn & sc_object::attr_cltn() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return *(sc_attr_cltn *)NULL; + return _gem5_object->attr_cltn(); } const sc_attr_cltn & sc_object::attr_cltn() const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return *(sc_attr_cltn *)NULL; + return _gem5_object->attr_cltn(); } sc_simcontext * sc_object::simcontext() const { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return nullptr; + return _gem5_object->simcontext(); } sc_object::sc_object() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _gem5_object = new sc_gem5::Object(this); } sc_object::sc_object(const char *name) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _gem5_object = new sc_gem5::Object(this, name); } -sc_object::sc_object(const sc_object &arg) +sc_object::sc_object(const sc_object &other) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _gem5_object = new sc_gem5::Object(this, *other._gem5_object); } sc_object & -sc_object::operator = (const sc_object &) +sc_object::operator = (const sc_object &other) { + *_gem5_object = *other._gem5_object; return *this; } sc_object::~sc_object() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + delete _gem5_object; } const std::vector & sc_get_top_level_objects() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return *(const std::vector *)nullptr; + return sc_gem5::topLevelObjects; } sc_object * -sc_find_object(const char *) +sc_find_object(const char *name) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return NULL; + return sc_gem5::findObject(name); } } // namespace sc_core diff --git a/src/systemc/ext/core/sc_object.hh b/src/systemc/ext/core/sc_object.hh index 653df874e..2dcc7faa7 100644 --- a/src/systemc/ext/core/sc_object.hh +++ b/src/systemc/ext/core/sc_object.hh @@ -34,6 +34,13 @@ #include #include +namespace sc_gem5 +{ + +class Object; + +} // namespace sc_gem5 + namespace sc_core { @@ -48,7 +55,7 @@ class sc_object const char *name() const; const char *basename() const; - virtual const char *kind() const; + virtual const char *kind() const { return "sc_object"; } virtual void print(std::ostream & =std::cout) const; virtual void dump(std::ostream & =std::cout) const; @@ -66,8 +73,7 @@ class sc_object const sc_attr_cltn &attr_cltn() const; // Deprecated - sc_simcontext * - simcontext() const; + sc_simcontext *simcontext() const; protected: sc_object(); @@ -75,6 +81,10 @@ class sc_object sc_object(const sc_object &); sc_object &operator = (const sc_object &); virtual ~sc_object(); + + private: + friend class sc_gem5::Object; + sc_gem5::Object *_gem5_object; }; const std::vector &sc_get_top_level_objects(); -- cgit v1.2.3