object.cc revision 13179:7445c43d036b
112027Sjungma@eit.uni-kl.de/*
212027Sjungma@eit.uni-kl.de * Copyright 2018 Google, Inc.
312027Sjungma@eit.uni-kl.de *
412027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without
512027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are
612027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright
712027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer;
812027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright
912027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the
1012027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution;
1112027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its
1212027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from
1312027Sjungma@eit.uni-kl.de * this software without specific prior written permission.
1412027Sjungma@eit.uni-kl.de *
1512027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1612027Sjungma@eit.uni-kl.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1712027Sjungma@eit.uni-kl.de * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812027Sjungma@eit.uni-kl.de * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1912027Sjungma@eit.uni-kl.de * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2012027Sjungma@eit.uni-kl.de * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2112027Sjungma@eit.uni-kl.de * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2212027Sjungma@eit.uni-kl.de * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2312027Sjungma@eit.uni-kl.de * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2412027Sjungma@eit.uni-kl.de * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2512027Sjungma@eit.uni-kl.de * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2612027Sjungma@eit.uni-kl.de *
2712027Sjungma@eit.uni-kl.de * Authors: Gabe Black
2812027Sjungma@eit.uni-kl.de */
2912027Sjungma@eit.uni-kl.de
3012027Sjungma@eit.uni-kl.de#include "systemc/core/object.hh"
3112027Sjungma@eit.uni-kl.de
3212027Sjungma@eit.uni-kl.de#include <algorithm>
3312027Sjungma@eit.uni-kl.de
3412027Sjungma@eit.uni-kl.de#include "base/logging.hh"
3512027Sjungma@eit.uni-kl.de#include "systemc/core/event.hh"
3612027Sjungma@eit.uni-kl.de#include "systemc/core/module.hh"
3712027Sjungma@eit.uni-kl.de#include "systemc/core/scheduler.hh"
3812027Sjungma@eit.uni-kl.de#include "systemc/ext/core/sc_module.hh"
3912027Sjungma@eit.uni-kl.de
4012027Sjungma@eit.uni-kl.denamespace sc_gem5
4112027Sjungma@eit.uni-kl.de{
4212027Sjungma@eit.uni-kl.de
4312027Sjungma@eit.uni-kl.denamespace
4412027Sjungma@eit.uni-kl.de{
4512027Sjungma@eit.uni-kl.de
4612027Sjungma@eit.uni-kl.deObjectsIt
4712027Sjungma@eit.uni-kl.defindObjectIn(Objects &objects, const std::string &name)
4812027Sjungma@eit.uni-kl.de{
4912027Sjungma@eit.uni-kl.de    ObjectsIt it;
5012027Sjungma@eit.uni-kl.de    for (it = objects.begin(); it != objects.end(); it++)
5112027Sjungma@eit.uni-kl.de        if (!strcmp((*it)->name(), name.c_str()))
5212027Sjungma@eit.uni-kl.de            break;
5312027Sjungma@eit.uni-kl.de
5412027Sjungma@eit.uni-kl.de    return it;
5512027Sjungma@eit.uni-kl.de}
5612027Sjungma@eit.uni-kl.de
5712027Sjungma@eit.uni-kl.devoid
5812027Sjungma@eit.uni-kl.deaddObject(Objects *objects, sc_core::sc_object *object)
5912027Sjungma@eit.uni-kl.de{
6012027Sjungma@eit.uni-kl.de    objects->emplace(objects->end(), object);
6112027Sjungma@eit.uni-kl.de}
6212027Sjungma@eit.uni-kl.de
6312027Sjungma@eit.uni-kl.devoid
6412027Sjungma@eit.uni-kl.depopObject(Objects *objects, const std::string &name)
6512027Sjungma@eit.uni-kl.de{
6612027Sjungma@eit.uni-kl.de    ObjectsIt it = findObjectIn(*objects, name);
6712027Sjungma@eit.uni-kl.de    assert(it != objects->end());
6812027Sjungma@eit.uni-kl.de    std::swap(objects->back(), *it);
6912027Sjungma@eit.uni-kl.de    objects->pop_back();
7012027Sjungma@eit.uni-kl.de}
7112027Sjungma@eit.uni-kl.de
7212027Sjungma@eit.uni-kl.debool
7312027Sjungma@eit.uni-kl.denameIsUnique(Objects *objects, Events *events, const std::string &name)
7412027Sjungma@eit.uni-kl.de{
7512027Sjungma@eit.uni-kl.de    for (auto obj: *objects)
7612027Sjungma@eit.uni-kl.de        if (!strcmp(obj->basename(), name.c_str()))
7712027Sjungma@eit.uni-kl.de            return false;
7812027Sjungma@eit.uni-kl.de    for (auto event: *events)
7912027Sjungma@eit.uni-kl.de        if (!strcmp(event->basename(), name.c_str()))
8012027Sjungma@eit.uni-kl.de            return false;
8112027Sjungma@eit.uni-kl.de    return true;
8212027Sjungma@eit.uni-kl.de}
8312027Sjungma@eit.uni-kl.de
8412027Sjungma@eit.uni-kl.de} // anonymous namespace
8512027Sjungma@eit.uni-kl.de
8612027Sjungma@eit.uni-kl.deObject::Object(sc_core::sc_object *_sc_obj) : Object(_sc_obj, nullptr) {}
8712027Sjungma@eit.uni-kl.de
8812027Sjungma@eit.uni-kl.deObject::Object(sc_core::sc_object *_sc_obj, const char *obj_name) :
8912027Sjungma@eit.uni-kl.de    _sc_obj(_sc_obj), _basename(obj_name ? obj_name : ""), parent(nullptr)
9012027Sjungma@eit.uni-kl.de{
9112027Sjungma@eit.uni-kl.de    if (_basename == "")
9212027Sjungma@eit.uni-kl.de        _basename = ::sc_core::sc_gen_unique_name("object");
9312027Sjungma@eit.uni-kl.de
9412027Sjungma@eit.uni-kl.de    Module *p = currentModule();
9512027Sjungma@eit.uni-kl.de    if (!p)
9612027Sjungma@eit.uni-kl.de        p = callbackModule();
9712027Sjungma@eit.uni-kl.de
9812027Sjungma@eit.uni-kl.de    Module *n = newModule();
9912027Sjungma@eit.uni-kl.de    if (n) {
10012027Sjungma@eit.uni-kl.de        // We are a module in the process of being constructed.
10112027Sjungma@eit.uni-kl.de        n->finish(this);
10212027Sjungma@eit.uni-kl.de    }
10312027Sjungma@eit.uni-kl.de
10412027Sjungma@eit.uni-kl.de    if (p) {
10512027Sjungma@eit.uni-kl.de        // We're "within" a parent module, ie we're being created while its
10612027Sjungma@eit.uni-kl.de        // constructor or end_of_elaboration callback is running.
10712027Sjungma@eit.uni-kl.de        parent = p->obj()->_sc_obj;
10812027Sjungma@eit.uni-kl.de    } else if (scheduler.current()) {
10912027Sjungma@eit.uni-kl.de        // Our parent is the currently running process.
11012027Sjungma@eit.uni-kl.de        parent = scheduler.current();
11112027Sjungma@eit.uni-kl.de    }
11212027Sjungma@eit.uni-kl.de
11312027Sjungma@eit.uni-kl.de    std::string original_name = _basename;
11412027Sjungma@eit.uni-kl.de    _basename = sc_gem5::pickUniqueName(parent, original_name);
11512027Sjungma@eit.uni-kl.de
11612027Sjungma@eit.uni-kl.de    if (parent)
11712027Sjungma@eit.uni-kl.de        addObject(&parent->_gem5_object->children, _sc_obj);
11812027Sjungma@eit.uni-kl.de    else
11912027Sjungma@eit.uni-kl.de        addObject(&topLevelObjects, _sc_obj);
12012027Sjungma@eit.uni-kl.de
12112027Sjungma@eit.uni-kl.de    addObject(&allObjects, _sc_obj);
12212027Sjungma@eit.uni-kl.de
12312027Sjungma@eit.uni-kl.de    sc_core::sc_object *sc_p = parent;
12412027Sjungma@eit.uni-kl.de    std::string path = "";
12512027Sjungma@eit.uni-kl.de    while (sc_p) {
12612027Sjungma@eit.uni-kl.de        path = std::string(sc_p->basename()) + std::string(".") + path;
12712027Sjungma@eit.uni-kl.de        sc_p = sc_p->get_parent_object();
12812027Sjungma@eit.uni-kl.de    }
12912027Sjungma@eit.uni-kl.de
13012027Sjungma@eit.uni-kl.de    if (_basename != original_name) {
13112027Sjungma@eit.uni-kl.de        std::string message = path + original_name +
13212027Sjungma@eit.uni-kl.de            ". Latter declaration will be renamed to " +
13312027Sjungma@eit.uni-kl.de            path + _basename;
13412027Sjungma@eit.uni-kl.de        SC_REPORT_WARNING("(W505) object already exists", message.c_str());
13512027Sjungma@eit.uni-kl.de    }
13612027Sjungma@eit.uni-kl.de    _name = path + _basename;
13712027Sjungma@eit.uni-kl.de}
13812027Sjungma@eit.uni-kl.de
13912027Sjungma@eit.uni-kl.deObject::Object(sc_core::sc_object *_sc_obj, const Object &arg) :
14012027Sjungma@eit.uni-kl.de    Object(_sc_obj, arg._basename.c_str())
14112027Sjungma@eit.uni-kl.de{}
14212027Sjungma@eit.uni-kl.de
14312027Sjungma@eit.uni-kl.deObject &
14412027Sjungma@eit.uni-kl.deObject::operator = (const Object &)
14512027Sjungma@eit.uni-kl.de{
14612027Sjungma@eit.uni-kl.de    return *this;
14712027Sjungma@eit.uni-kl.de}
14812027Sjungma@eit.uni-kl.de
14912027Sjungma@eit.uni-kl.deObject::~Object()
15012027Sjungma@eit.uni-kl.de{
15112027Sjungma@eit.uni-kl.de    // Promote all children to be top level objects.
15212027Sjungma@eit.uni-kl.de    for (auto child: children) {
15312027Sjungma@eit.uni-kl.de        addObject(&topLevelObjects, child);
15412027Sjungma@eit.uni-kl.de        child->_gem5_object->parent = nullptr;
15512027Sjungma@eit.uni-kl.de    }
15612027Sjungma@eit.uni-kl.de    children.clear();
15712027Sjungma@eit.uni-kl.de
15812027Sjungma@eit.uni-kl.de    if (parent)
15912027Sjungma@eit.uni-kl.de        popObject(&parent->_gem5_object->children, _name);
16012027Sjungma@eit.uni-kl.de    else
16112027Sjungma@eit.uni-kl.de        popObject(&topLevelObjects, _name);
16212027Sjungma@eit.uni-kl.de    popObject(&allObjects, _name);
16312027Sjungma@eit.uni-kl.de}
16412027Sjungma@eit.uni-kl.de
16512027Sjungma@eit.uni-kl.deconst char *
16612027Sjungma@eit.uni-kl.deObject::name() const
16712027Sjungma@eit.uni-kl.de{
16812027Sjungma@eit.uni-kl.de    return _name.c_str();
16912027Sjungma@eit.uni-kl.de}
17012027Sjungma@eit.uni-kl.de
17112027Sjungma@eit.uni-kl.deconst char *
17212027Sjungma@eit.uni-kl.deObject::basename() const
17312027Sjungma@eit.uni-kl.de{
17412027Sjungma@eit.uni-kl.de    return _basename.c_str();
17512027Sjungma@eit.uni-kl.de}
17612027Sjungma@eit.uni-kl.de
17712027Sjungma@eit.uni-kl.devoid
17812027Sjungma@eit.uni-kl.deObject::print(std::ostream &out) const
17912027Sjungma@eit.uni-kl.de{
18012027Sjungma@eit.uni-kl.de    out << name();
18112027Sjungma@eit.uni-kl.de}
18212027Sjungma@eit.uni-kl.de
18312027Sjungma@eit.uni-kl.devoid
18412027Sjungma@eit.uni-kl.deObject::dump(std::ostream &out) const
18512027Sjungma@eit.uni-kl.de{
18612027Sjungma@eit.uni-kl.de    out << "name = " << name() << "\n";
18712027Sjungma@eit.uni-kl.de    out << "kind = " << _sc_obj->kind() << "\n";
18812027Sjungma@eit.uni-kl.de}
18912027Sjungma@eit.uni-kl.de
19012027Sjungma@eit.uni-kl.deconst std::vector<sc_core::sc_object *> &
19112027Sjungma@eit.uni-kl.deObject::get_child_objects() const
19212027Sjungma@eit.uni-kl.de{
19312027Sjungma@eit.uni-kl.de    return children;
19412027Sjungma@eit.uni-kl.de}
19512027Sjungma@eit.uni-kl.de
19612027Sjungma@eit.uni-kl.deconst std::vector<sc_core::sc_event *> &
19712027Sjungma@eit.uni-kl.deObject::get_child_events() const
19812027Sjungma@eit.uni-kl.de{
19912027Sjungma@eit.uni-kl.de    return events;
20012027Sjungma@eit.uni-kl.de}
20112027Sjungma@eit.uni-kl.de
20212027Sjungma@eit.uni-kl.desc_core::sc_object *Object::get_parent_object() const
20312027Sjungma@eit.uni-kl.de{
20412027Sjungma@eit.uni-kl.de    return parent;
20512027Sjungma@eit.uni-kl.de}
206
207bool
208Object::add_attribute(sc_core::sc_attr_base &attr)
209{
210    return cltn.push_back(&attr);
211}
212
213sc_core::sc_attr_base *
214Object::get_attribute(const std::string &attr)
215{
216    return cltn[attr];
217}
218
219sc_core::sc_attr_base *
220Object::remove_attribute(const std::string &attr)
221{
222    return cltn.remove(attr);
223}
224
225void
226Object::remove_all_attributes()
227{
228    cltn.remove_all();
229}
230
231int
232Object::num_attributes() const
233{
234    return cltn.size();
235}
236
237sc_core::sc_attr_cltn &
238Object::attr_cltn()
239{
240    return cltn;
241}
242
243const sc_core::sc_attr_cltn &
244Object::attr_cltn() const
245{
246    return cltn;
247}
248
249sc_core::sc_simcontext *
250Object::simcontext() const
251{
252    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
253    return nullptr;
254}
255
256EventsIt
257Object::addChildEvent(sc_core::sc_event *e)
258{
259    return events.emplace(events.end(), e);
260}
261
262void
263Object::delChildEvent(sc_core::sc_event *e)
264{
265    EventsIt it = std::find(events.begin(), events.end(), e);
266    assert(it != events.end());
267    std::swap(*it, events.back());
268    events.pop_back();
269}
270
271std::string
272Object::pickUniqueName(std::string base)
273{
274    std::string seed = base;
275    while (!nameIsUnique(&children, &events, base))
276        base = ::sc_core::sc_gen_unique_name(seed.c_str());
277
278    return base;
279}
280
281std::string
282pickUniqueName(::sc_core::sc_object *parent, std::string base)
283{
284    if (parent)
285        return Object::getFromScObject(parent)->pickUniqueName(base);
286
287    std::string seed = base;
288    while (!nameIsUnique(&topLevelObjects, &topLevelEvents, base))
289        base = ::sc_core::sc_gen_unique_name(seed.c_str());
290
291    return base;
292}
293
294
295Objects topLevelObjects;
296Objects allObjects;
297
298const std::vector<sc_core::sc_object *> &
299getTopLevelScObjects()
300{
301    return topLevelObjects;
302}
303
304sc_core::sc_object *
305findObject(const char *name, const Objects &objects)
306{
307    ObjectsIt it = findObjectIn(allObjects, name);
308    return it == allObjects.end() ? nullptr : *it;
309}
310
311} // namespace sc_gem5
312