summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-06-22 14:19:44 -0700
committerGabe Black <gabeblack@google.com>2018-09-05 06:01:39 +0000
commit9bd3bb7bc804a16b2f0de03fa6d3d9d0928f38a2 (patch)
treea9500949c781d55fea96bf9fb7098a9639b7af5a
parent97018a3b20c129a3413011d205f18189dd1a75c9 (diff)
downloadgem5-9bd3bb7bc804a16b2f0de03fa6d3d9d0928f38a2.tar.xz
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 <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r--src/systemc/core/SConscript1
-rw-r--r--src/systemc/core/module.cc37
-rw-r--r--src/systemc/core/module.hh45
-rw-r--r--src/systemc/core/object.cc236
-rw-r--r--src/systemc/core/object.hh103
-rw-r--r--src/systemc/core/sc_module_name.cc6
-rw-r--r--src/systemc/core/sc_object.cc85
-rw-r--r--src/systemc/ext/core/sc_object.hh16
8 files changed, 454 insertions, 75 deletions
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 <cassert>
#include <list>
#include "base/logging.hh"
-namespace SystemC
+namespace sc_gem5
{
namespace
{
std::list<Module *> _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 <cassert>
+
+#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<sc_core::sc_object *> &
+Object::get_child_objects() const
+{
+ return children;
+}
+
+const std::vector<sc_core::sc_event *> &
+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<sc_core::sc_object *> &
+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 <string>
+#include <vector>
+
+#include "systemc/ext/core/sc_attr.hh"
+#include "systemc/ext/core/sc_object.hh"
+
+namespace sc_gem5
+{
+
+class Object;
+
+typedef std::vector<sc_core::sc_object *> Objects;
+typedef std::vector<sc_core::sc_event *> 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<sc_core::sc_object *> &get_child_objects() const;
+ const std::vector<sc_core::sc_event *> &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 <vector>
+
#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<sc_object *> 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 *> &
sc_object::get_child_objects() const
{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
- return *(const std::vector<sc_object *> *)nullptr;
+ return _gem5_object->get_child_objects();
}
const std::vector<sc_event *> &
sc_object::get_child_events() const
{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
- return *(const std::vector<sc_event *> *)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_object *> &
sc_get_top_level_objects()
{
- warn("%s not implemented.\n", __PRETTY_FUNCTION__);
- return *(const std::vector<sc_object *> *)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 <string>
#include <vector>
+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_object *> &sc_get_top_level_objects();