object.cc revision 12984:02f20eeeb8ce
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#include "systemc/core/object.hh"
31
32#include "base/logging.hh"
33#include "systemc/core/module.hh"
34#include "systemc/core/scheduler.hh"
35
36namespace sc_gem5
37{
38
39namespace
40{
41
42ObjectsIt
43findObjectIn(Objects &objects, const std::string &name)
44{
45    ObjectsIt it;
46    for (it = objects.begin(); it != objects.end(); it++)
47        if (!strcmp((*it)->name(), name.c_str()))
48            break;
49
50    return it;
51}
52
53void
54addObject(Objects *objects, sc_core::sc_object *object)
55{
56    objects->emplace(objects->end(), object);
57}
58
59void
60popObject(Objects *objects, const std::string &name)
61{
62    ObjectsIt it = findObjectIn(*objects, name);
63    assert(it != objects->end());
64    std::swap(objects->back(), *it);
65    objects->pop_back();
66}
67
68} // anonymous namespace
69
70Object::Object(sc_core::sc_object *_sc_obj) : Object(_sc_obj, "object") {}
71
72Object::Object(sc_core::sc_object *_sc_obj, const char *obj_name) :
73    _sc_obj(_sc_obj), _basename(obj_name), parent(nullptr)
74{
75    if (_basename == "")
76        _basename = "object";
77
78    Module *p = currentModule();
79
80    Module *n = newModule();
81    if (n) {
82        // We are a module in the process of being constructed.
83        n->finish(this);
84    }
85
86    if (p) {
87        // We're "within" a parent module, ie we're being created while its
88        // constructor is running.
89        parent = p->obj()->_sc_obj;
90        addObject(&parent->_gem5_object->children, _sc_obj);
91    } else if (scheduler.current()) {
92        // Our parent is the currently running process.
93        parent = scheduler.current();
94    } else {
95        // We're a top level object.
96        addObject(&topLevelObjects, _sc_obj);
97    }
98
99    addObject(&allObjects, _sc_obj);
100
101    _name = _basename;
102    sc_core::sc_object *sc_p = parent;
103    while (sc_p) {
104        _name = std::string(sc_p->basename()) + std::string(".") + _name;
105        sc_p = sc_p->get_parent_object();
106    }
107}
108
109Object::Object(sc_core::sc_object *_sc_obj, const Object &arg) :
110    Object(_sc_obj, arg._basename.c_str())
111{}
112
113Object &
114Object::operator = (const Object &)
115{
116    return *this;
117}
118
119Object::~Object()
120{
121    // Promote all children to be top level objects.
122    for (auto child: children) {
123        addObject(&topLevelObjects, child);
124        child->_gem5_object->parent = nullptr;
125    }
126    children.clear();
127
128    if (parent)
129        popObject(&parent->_gem5_object->children, _name);
130    else
131        popObject(&topLevelObjects, _name);
132    popObject(&allObjects, _name);
133}
134
135const char *
136Object::name() const
137{
138    return _name.c_str();
139}
140
141const char *
142Object::basename() const
143{
144    return _basename.c_str();
145}
146
147void
148Object::print(std::ostream &out) const
149{
150    out << name();
151}
152
153void
154Object::dump(std::ostream &out) const
155{
156    out << "name = " << name() << "\n";
157    out << "kind = " << _sc_obj->kind() << "\n";
158}
159
160const std::vector<sc_core::sc_object *> &
161Object::get_child_objects() const
162{
163    return children;
164}
165
166const std::vector<sc_core::sc_event *> &
167Object::get_child_events() const
168{
169    return events;
170}
171
172sc_core::sc_object *Object::get_parent_object() const
173{
174    return parent;
175}
176
177bool
178Object::add_attribute(sc_core::sc_attr_base &attr)
179{
180    return cltn.push_back(&attr);
181}
182
183sc_core::sc_attr_base *
184Object::get_attribute(const std::string &attr)
185{
186    return cltn[attr];
187}
188
189sc_core::sc_attr_base *
190Object::remove_attribute(const std::string &attr)
191{
192    return cltn.remove(attr);
193}
194
195void
196Object::remove_all_attributes()
197{
198    cltn.remove_all();
199}
200
201int
202Object::num_attributes() const
203{
204    return cltn.size();
205}
206
207sc_core::sc_attr_cltn &
208Object::attr_cltn()
209{
210    return cltn;
211}
212
213const sc_core::sc_attr_cltn &
214Object::attr_cltn() const
215{
216    return cltn;
217}
218
219sc_core::sc_simcontext *
220Object::simcontext() const
221{
222    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
223    return nullptr;
224}
225
226EventsIt
227Object::addChildEvent(sc_core::sc_event *e)
228{
229    return events.emplace(events.end(), e);
230}
231
232void
233Object::delChildEvent(EventsIt it)
234{
235    std::swap(*it, events.back());
236    events.pop_back();
237}
238
239
240Objects topLevelObjects;
241Objects allObjects;
242
243const std::vector<sc_core::sc_object *> &
244getTopLevelScObjects()
245{
246    return topLevelObjects;
247}
248
249sc_core::sc_object *
250findObject(const char *name, const Objects &objects)
251{
252    ObjectsIt it = findObjectIn(allObjects, name);
253    return it == allObjects.end() ? nullptr : *it;
254}
255
256} // namespace sc_gem5
257