object.cc (13127:d3318222cf09) object.cc (13161:8bef8ce2784f)
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 <algorithm>
33
34#include "base/logging.hh"
35#include "systemc/core/event.hh"
36#include "systemc/core/module.hh"
37#include "systemc/core/scheduler.hh"
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 <algorithm>
33
34#include "base/logging.hh"
35#include "systemc/core/event.hh"
36#include "systemc/core/module.hh"
37#include "systemc/core/scheduler.hh"
38#include "systemc/ext/core/sc_module.hh"
38
39namespace sc_gem5
40{
41
42namespace
43{
44
45ObjectsIt
46findObjectIn(Objects &objects, const std::string &name)
47{
48 ObjectsIt it;
49 for (it = objects.begin(); it != objects.end(); it++)
50 if (!strcmp((*it)->name(), name.c_str()))
51 break;
52
53 return it;
54}
55
56void
57addObject(Objects *objects, sc_core::sc_object *object)
58{
59 objects->emplace(objects->end(), object);
60}
61
62void
63popObject(Objects *objects, const std::string &name)
64{
65 ObjectsIt it = findObjectIn(*objects, name);
66 assert(it != objects->end());
67 std::swap(objects->back(), *it);
68 objects->pop_back();
69}
70
71bool
72nameIsUnique(Objects *objects, Events *events, const std::string &name)
73{
74 for (auto obj: *objects)
75 if (!strcmp(obj->basename(), name.c_str()))
76 return false;
77 for (auto event: *events)
78 if (!strcmp(event->basename(), name.c_str()))
79 return false;
80 return true;
81}
82
83} // anonymous namespace
84
39
40namespace sc_gem5
41{
42
43namespace
44{
45
46ObjectsIt
47findObjectIn(Objects &objects, const std::string &name)
48{
49 ObjectsIt it;
50 for (it = objects.begin(); it != objects.end(); it++)
51 if (!strcmp((*it)->name(), name.c_str()))
52 break;
53
54 return it;
55}
56
57void
58addObject(Objects *objects, sc_core::sc_object *object)
59{
60 objects->emplace(objects->end(), object);
61}
62
63void
64popObject(Objects *objects, const std::string &name)
65{
66 ObjectsIt it = findObjectIn(*objects, name);
67 assert(it != objects->end());
68 std::swap(objects->back(), *it);
69 objects->pop_back();
70}
71
72bool
73nameIsUnique(Objects *objects, Events *events, const std::string &name)
74{
75 for (auto obj: *objects)
76 if (!strcmp(obj->basename(), name.c_str()))
77 return false;
78 for (auto event: *events)
79 if (!strcmp(event->basename(), name.c_str()))
80 return false;
81 return true;
82}
83
84} // anonymous namespace
85
85Object::Object(sc_core::sc_object *_sc_obj) : Object(_sc_obj, "object") {}
86Object::Object(sc_core::sc_object *_sc_obj) : Object(_sc_obj, nullptr) {}
86
87Object::Object(sc_core::sc_object *_sc_obj, const char *obj_name) :
88 _sc_obj(_sc_obj), _basename(obj_name ? obj_name : ""), parent(nullptr)
89{
90 if (_basename == "")
87
88Object::Object(sc_core::sc_object *_sc_obj, const char *obj_name) :
89 _sc_obj(_sc_obj), _basename(obj_name ? obj_name : ""), parent(nullptr)
90{
91 if (_basename == "")
91 _basename = "object";
92 _basename = ::sc_core::sc_gen_unique_name("object");
92
93 Module *p = currentModule();
94 if (!p)
95 p = callbackModule();
96
97 Module *n = newModule();
98 if (n) {
99 // We are a module in the process of being constructed.
100 n->finish(this);
101 }
102
103 if (p) {
104 // We're "within" a parent module, ie we're being created while its
105 // constructor or end_of_elaboration callback is running.
106 parent = p->obj()->_sc_obj;
107 } else if (scheduler.current()) {
108 // Our parent is the currently running process.
109 parent = scheduler.current();
110 }
111
112 sc_gem5::pickUniqueName(parent, _basename);
113
114 if (parent)
115 addObject(&parent->_gem5_object->children, _sc_obj);
116 else
117 addObject(&topLevelObjects, _sc_obj);
118
119 addObject(&allObjects, _sc_obj);
120
121 _name = _basename;
122 sc_core::sc_object *sc_p = parent;
123 while (sc_p) {
124 _name = std::string(sc_p->basename()) + std::string(".") + _name;
125 sc_p = sc_p->get_parent_object();
126 }
127}
128
129Object::Object(sc_core::sc_object *_sc_obj, const Object &arg) :
130 Object(_sc_obj, arg._basename.c_str())
131{}
132
133Object &
134Object::operator = (const Object &)
135{
136 return *this;
137}
138
139Object::~Object()
140{
141 // Promote all children to be top level objects.
142 for (auto child: children) {
143 addObject(&topLevelObjects, child);
144 child->_gem5_object->parent = nullptr;
145 }
146 children.clear();
147
148 if (parent)
149 popObject(&parent->_gem5_object->children, _name);
150 else
151 popObject(&topLevelObjects, _name);
152 popObject(&allObjects, _name);
153}
154
155const char *
156Object::name() const
157{
158 return _name.c_str();
159}
160
161const char *
162Object::basename() const
163{
164 return _basename.c_str();
165}
166
167void
168Object::print(std::ostream &out) const
169{
170 out << name();
171}
172
173void
174Object::dump(std::ostream &out) const
175{
176 out << "name = " << name() << "\n";
177 out << "kind = " << _sc_obj->kind() << "\n";
178}
179
180const std::vector<sc_core::sc_object *> &
181Object::get_child_objects() const
182{
183 return children;
184}
185
186const std::vector<sc_core::sc_event *> &
187Object::get_child_events() const
188{
189 return events;
190}
191
192sc_core::sc_object *Object::get_parent_object() const
193{
194 return parent;
195}
196
197bool
198Object::add_attribute(sc_core::sc_attr_base &attr)
199{
200 return cltn.push_back(&attr);
201}
202
203sc_core::sc_attr_base *
204Object::get_attribute(const std::string &attr)
205{
206 return cltn[attr];
207}
208
209sc_core::sc_attr_base *
210Object::remove_attribute(const std::string &attr)
211{
212 return cltn.remove(attr);
213}
214
215void
216Object::remove_all_attributes()
217{
218 cltn.remove_all();
219}
220
221int
222Object::num_attributes() const
223{
224 return cltn.size();
225}
226
227sc_core::sc_attr_cltn &
228Object::attr_cltn()
229{
230 return cltn;
231}
232
233const sc_core::sc_attr_cltn &
234Object::attr_cltn() const
235{
236 return cltn;
237}
238
239sc_core::sc_simcontext *
240Object::simcontext() const
241{
242 warn("%s not implemented.\n", __PRETTY_FUNCTION__);
243 return nullptr;
244}
245
246EventsIt
247Object::addChildEvent(sc_core::sc_event *e)
248{
249 return events.emplace(events.end(), e);
250}
251
252void
253Object::delChildEvent(sc_core::sc_event *e)
254{
255 EventsIt it = std::find(events.begin(), events.end(), e);
256 assert(it != events.end());
257 std::swap(*it, events.back());
258 events.pop_back();
259}
260
261void
262Object::pickUniqueName(std::string &base)
263{
264 std::string seed = base;
265 while (!nameIsUnique(&children, &events, base))
266 base = ::sc_core::sc_gen_unique_name(seed.c_str());
267}
268
269void
270pickUniqueName(::sc_core::sc_object *parent, std::string &base)
271{
272 if (parent) {
273 Object::getFromScObject(parent)->pickUniqueName(base);
274 return;
275 }
276
277 std::string seed = base;
278 while (!nameIsUnique(&topLevelObjects, &topLevelEvents, base))
279 base = ::sc_core::sc_gen_unique_name(seed.c_str());
280}
281
282
283Objects topLevelObjects;
284Objects allObjects;
285
286const std::vector<sc_core::sc_object *> &
287getTopLevelScObjects()
288{
289 return topLevelObjects;
290}
291
292sc_core::sc_object *
293findObject(const char *name, const Objects &objects)
294{
295 ObjectsIt it = findObjectIn(allObjects, name);
296 return it == allObjects.end() ? nullptr : *it;
297}
298
299} // namespace sc_gem5
93
94 Module *p = currentModule();
95 if (!p)
96 p = callbackModule();
97
98 Module *n = newModule();
99 if (n) {
100 // We are a module in the process of being constructed.
101 n->finish(this);
102 }
103
104 if (p) {
105 // We're "within" a parent module, ie we're being created while its
106 // constructor or end_of_elaboration callback is running.
107 parent = p->obj()->_sc_obj;
108 } else if (scheduler.current()) {
109 // Our parent is the currently running process.
110 parent = scheduler.current();
111 }
112
113 sc_gem5::pickUniqueName(parent, _basename);
114
115 if (parent)
116 addObject(&parent->_gem5_object->children, _sc_obj);
117 else
118 addObject(&topLevelObjects, _sc_obj);
119
120 addObject(&allObjects, _sc_obj);
121
122 _name = _basename;
123 sc_core::sc_object *sc_p = parent;
124 while (sc_p) {
125 _name = std::string(sc_p->basename()) + std::string(".") + _name;
126 sc_p = sc_p->get_parent_object();
127 }
128}
129
130Object::Object(sc_core::sc_object *_sc_obj, const Object &arg) :
131 Object(_sc_obj, arg._basename.c_str())
132{}
133
134Object &
135Object::operator = (const Object &)
136{
137 return *this;
138}
139
140Object::~Object()
141{
142 // Promote all children to be top level objects.
143 for (auto child: children) {
144 addObject(&topLevelObjects, child);
145 child->_gem5_object->parent = nullptr;
146 }
147 children.clear();
148
149 if (parent)
150 popObject(&parent->_gem5_object->children, _name);
151 else
152 popObject(&topLevelObjects, _name);
153 popObject(&allObjects, _name);
154}
155
156const char *
157Object::name() const
158{
159 return _name.c_str();
160}
161
162const char *
163Object::basename() const
164{
165 return _basename.c_str();
166}
167
168void
169Object::print(std::ostream &out) const
170{
171 out << name();
172}
173
174void
175Object::dump(std::ostream &out) const
176{
177 out << "name = " << name() << "\n";
178 out << "kind = " << _sc_obj->kind() << "\n";
179}
180
181const std::vector<sc_core::sc_object *> &
182Object::get_child_objects() const
183{
184 return children;
185}
186
187const std::vector<sc_core::sc_event *> &
188Object::get_child_events() const
189{
190 return events;
191}
192
193sc_core::sc_object *Object::get_parent_object() const
194{
195 return parent;
196}
197
198bool
199Object::add_attribute(sc_core::sc_attr_base &attr)
200{
201 return cltn.push_back(&attr);
202}
203
204sc_core::sc_attr_base *
205Object::get_attribute(const std::string &attr)
206{
207 return cltn[attr];
208}
209
210sc_core::sc_attr_base *
211Object::remove_attribute(const std::string &attr)
212{
213 return cltn.remove(attr);
214}
215
216void
217Object::remove_all_attributes()
218{
219 cltn.remove_all();
220}
221
222int
223Object::num_attributes() const
224{
225 return cltn.size();
226}
227
228sc_core::sc_attr_cltn &
229Object::attr_cltn()
230{
231 return cltn;
232}
233
234const sc_core::sc_attr_cltn &
235Object::attr_cltn() const
236{
237 return cltn;
238}
239
240sc_core::sc_simcontext *
241Object::simcontext() const
242{
243 warn("%s not implemented.\n", __PRETTY_FUNCTION__);
244 return nullptr;
245}
246
247EventsIt
248Object::addChildEvent(sc_core::sc_event *e)
249{
250 return events.emplace(events.end(), e);
251}
252
253void
254Object::delChildEvent(sc_core::sc_event *e)
255{
256 EventsIt it = std::find(events.begin(), events.end(), e);
257 assert(it != events.end());
258 std::swap(*it, events.back());
259 events.pop_back();
260}
261
262void
263Object::pickUniqueName(std::string &base)
264{
265 std::string seed = base;
266 while (!nameIsUnique(&children, &events, base))
267 base = ::sc_core::sc_gen_unique_name(seed.c_str());
268}
269
270void
271pickUniqueName(::sc_core::sc_object *parent, std::string &base)
272{
273 if (parent) {
274 Object::getFromScObject(parent)->pickUniqueName(base);
275 return;
276 }
277
278 std::string seed = base;
279 while (!nameIsUnique(&topLevelObjects, &topLevelEvents, base))
280 base = ::sc_core::sc_gen_unique_name(seed.c_str());
281}
282
283
284Objects topLevelObjects;
285Objects allObjects;
286
287const std::vector<sc_core::sc_object *> &
288getTopLevelScObjects()
289{
290 return topLevelObjects;
291}
292
293sc_core::sc_object *
294findObject(const char *name, const Objects &objects)
295{
296 ObjectsIt it = findObjectIn(allObjects, name);
297 return it == allObjects.end() ? nullptr : *it;
298}
299
300} // namespace sc_gem5