object.cc revision 13295
112841Sgabeblack@google.com/*
212841Sgabeblack@google.com * Copyright 2018 Google, Inc.
312841Sgabeblack@google.com *
412841Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
512841Sgabeblack@google.com * modification, are permitted provided that the following conditions are
612841Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
712841Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
812841Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
912841Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1012841Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1112841Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1212841Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1312841Sgabeblack@google.com * this software without specific prior written permission.
1412841Sgabeblack@google.com *
1512841Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1612841Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1712841Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812841Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1912841Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2012841Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2112841Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2212841Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2312841Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2412841Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2512841Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2612841Sgabeblack@google.com *
2712841Sgabeblack@google.com * Authors: Gabe Black
2812841Sgabeblack@google.com */
2912841Sgabeblack@google.com
3012841Sgabeblack@google.com#include "systemc/core/object.hh"
3112841Sgabeblack@google.com
3212841Sgabeblack@google.com#include <algorithm>
3313123Sgabeblack@google.com#include <stack>
3413274Sgabeblack@google.com
3513123Sgabeblack@google.com#include "base/logging.hh"
3612841Sgabeblack@google.com#include "systemc/core/event.hh"
3712841Sgabeblack@google.com#include "systemc/core/module.hh"
3813274Sgabeblack@google.com#include "systemc/core/scheduler.hh"
3912841Sgabeblack@google.com#include "systemc/ext/core/sc_module.hh"
4012841Sgabeblack@google.com
4112841Sgabeblack@google.comnamespace sc_gem5
4212841Sgabeblack@google.com{
4312841Sgabeblack@google.com
4412841Sgabeblack@google.comnamespace
4512841Sgabeblack@google.com{
4612841Sgabeblack@google.com
4712841Sgabeblack@google.comObjectsIt
4812841Sgabeblack@google.comfindObjectIn(Objects &objects, const std::string &name)
4912841Sgabeblack@google.com{
5012841Sgabeblack@google.com    ObjectsIt it;
5112841Sgabeblack@google.com    for (it = objects.begin(); it != objects.end(); it++)
5212841Sgabeblack@google.com        if (!strcmp((*it)->name(), name.c_str()))
5312841Sgabeblack@google.com            break;
5412841Sgabeblack@google.com
5512841Sgabeblack@google.com    return it;
5613123Sgabeblack@google.com}
5713274Sgabeblack@google.com
5812841Sgabeblack@google.comvoid
5912841Sgabeblack@google.comaddObject(Objects *objects, sc_core::sc_object *object)
6012841Sgabeblack@google.com{
6113274Sgabeblack@google.com    objects->emplace(objects->end(), object);
6213274Sgabeblack@google.com}
6312841Sgabeblack@google.com
6412841Sgabeblack@google.comvoid
6512841Sgabeblack@google.compopObject(Objects *objects, const std::string &name)
6612841Sgabeblack@google.com{
6713274Sgabeblack@google.com    ObjectsIt it = findObjectIn(*objects, name);
6812841Sgabeblack@google.com    assert(it != objects->end());
6913274Sgabeblack@google.com    std::swap(objects->back(), *it);
7013274Sgabeblack@google.com    objects->pop_back();
7113274Sgabeblack@google.com}
7213274Sgabeblack@google.com
7313274Sgabeblack@google.combool
7413274Sgabeblack@google.comnameIsUnique(Objects *objects, Events *events, const std::string &name)
7513274Sgabeblack@google.com{
7613274Sgabeblack@google.com    for (auto obj: *objects)
7713274Sgabeblack@google.com        if (!strcmp(obj->basename(), name.c_str()))
7813274Sgabeblack@google.com            return false;
7913274Sgabeblack@google.com    for (auto event: *events)
8013274Sgabeblack@google.com        if (!strcmp(event->basename(), name.c_str()))
8113274Sgabeblack@google.com            return false;
8213274Sgabeblack@google.com    return true;
8313274Sgabeblack@google.com}
8413274Sgabeblack@google.com
8513274Sgabeblack@google.com} // anonymous namespace
8613274Sgabeblack@google.com
8713274Sgabeblack@google.comObject::Object(sc_core::sc_object *_sc_obj) : Object(_sc_obj, nullptr) {}
8813274Sgabeblack@google.com
8913274Sgabeblack@google.comObject::Object(sc_core::sc_object *_sc_obj, const char *obj_name) :
9012841Sgabeblack@google.com    _sc_obj(_sc_obj), _basename(obj_name ? obj_name : ""), parent(nullptr)
9112841Sgabeblack@google.com{
9212841Sgabeblack@google.com    if (_basename == "")
9313123Sgabeblack@google.com        _basename = ::sc_core::sc_gen_unique_name("object");
9412841Sgabeblack@google.com
9513123Sgabeblack@google.com    parent = pickParentObj();
9613123Sgabeblack@google.com
9713123Sgabeblack@google.com    Module *n = newModule();
9813123Sgabeblack@google.com    if (n) {
9913123Sgabeblack@google.com        // We are a module in the process of being constructed.
10013123Sgabeblack@google.com        n->finish(this);
10112841Sgabeblack@google.com    }
10212841Sgabeblack@google.com
10312841Sgabeblack@google.com    std::string original_name = _basename;
10412841Sgabeblack@google.com    _basename = sc_gem5::pickUniqueName(parent, original_name);
10513123Sgabeblack@google.com
10613123Sgabeblack@google.com    if (parent)
10713123Sgabeblack@google.com        addObject(&parent->_gem5_object->children, _sc_obj);
10812841Sgabeblack@google.com    else
10912841Sgabeblack@google.com        addObject(&topLevelObjects, _sc_obj);
11013123Sgabeblack@google.com
11112841Sgabeblack@google.com    addObject(&allObjects, _sc_obj);
11213123Sgabeblack@google.com
11313123Sgabeblack@google.com    sc_core::sc_object *sc_p = parent;
11413123Sgabeblack@google.com    std::string path = "";
11513123Sgabeblack@google.com    while (sc_p) {
11613123Sgabeblack@google.com        path = std::string(sc_p->basename()) + std::string(".") + path;
11713123Sgabeblack@google.com        sc_p = sc_p->get_parent_object();
11812841Sgabeblack@google.com    }
11913123Sgabeblack@google.com
12012841Sgabeblack@google.com    if (_basename != original_name) {
12112841Sgabeblack@google.com        std::string message = path + original_name +
12213123Sgabeblack@google.com            ". Latter declaration will be renamed to " +
12312841Sgabeblack@google.com            path + _basename;
12413123Sgabeblack@google.com        SC_REPORT_WARNING("(W505) object already exists", message.c_str());
12513123Sgabeblack@google.com    }
12613123Sgabeblack@google.com    _name = path + _basename;
12713123Sgabeblack@google.com}
12812841Sgabeblack@google.com
12912841Sgabeblack@google.comObject::Object(sc_core::sc_object *_sc_obj, const Object &arg) :
13013123Sgabeblack@google.com    Object(_sc_obj, arg._basename.c_str())
13112841Sgabeblack@google.com{}
13213123Sgabeblack@google.com
13313123Sgabeblack@google.comObject &
13413123Sgabeblack@google.comObject::operator = (const Object &)
13513123Sgabeblack@google.com{
13613123Sgabeblack@google.com    return *this;
13713123Sgabeblack@google.com}
13812841Sgabeblack@google.com
13912841Sgabeblack@google.comObject::~Object()
14013123Sgabeblack@google.com{
14112841Sgabeblack@google.com    // Promote all children to be top level objects.
14213123Sgabeblack@google.com    for (auto child: children) {
14312841Sgabeblack@google.com        addObject(&topLevelObjects, child);
14412841Sgabeblack@google.com        child->_gem5_object->parent = nullptr;
14512841Sgabeblack@google.com    }
14612841Sgabeblack@google.com    children.clear();
14712853Sgabeblack@google.com
14812841Sgabeblack@google.com    for (auto event: events)
14913123Sgabeblack@google.com        Event::getFromScEvent(event)->clearParent();
15012841Sgabeblack@google.com
15112841Sgabeblack@google.com    if (parent)
15212841Sgabeblack@google.com        popObject(&parent->_gem5_object->children, _name);
15312841Sgabeblack@google.com    else
15413123Sgabeblack@google.com        popObject(&topLevelObjects, _name);
15512841Sgabeblack@google.com    popObject(&allObjects, _name);
15612841Sgabeblack@google.com}
15713123Sgabeblack@google.com
15812841Sgabeblack@google.comconst char *
15912841Sgabeblack@google.comObject::name() const
16012841Sgabeblack@google.com{
16113123Sgabeblack@google.com    return _name.c_str();
16212841Sgabeblack@google.com}
16312841Sgabeblack@google.com
16412841Sgabeblack@google.comconst char *
16513123Sgabeblack@google.comObject::basename() const
16612841Sgabeblack@google.com{
16713143Sgabeblack@google.com    return _basename.c_str();
16813143Sgabeblack@google.com}
16913143Sgabeblack@google.com
17013143Sgabeblack@google.comvoid
17113123Sgabeblack@google.comObject::print(std::ostream &out) const
17213123Sgabeblack@google.com{
17313123Sgabeblack@google.com    out << name();
17413123Sgabeblack@google.com}
17512841Sgabeblack@google.com
17612841Sgabeblack@google.comvoid
17713143Sgabeblack@google.comObject::dump(std::ostream &out) const
17812841Sgabeblack@google.com{
17913143Sgabeblack@google.com    out << "name = " << name() << "\n";
18013143Sgabeblack@google.com    out << "kind = " << _sc_obj->kind() << "\n";
18113143Sgabeblack@google.com}
18213143Sgabeblack@google.com
18313143Sgabeblack@google.comconst std::vector<sc_core::sc_object *> &
18413143Sgabeblack@google.comObject::get_child_objects() const
18513143Sgabeblack@google.com{
18613143Sgabeblack@google.com    return children;
18713143Sgabeblack@google.com}
18813143Sgabeblack@google.com
18912841Sgabeblack@google.comconst std::vector<sc_core::sc_event *> &
19012841Sgabeblack@google.comObject::get_child_events() const
19112841Sgabeblack@google.com{
19212841Sgabeblack@google.com    return events;
19312841Sgabeblack@google.com}
19412841Sgabeblack@google.com
19512841Sgabeblack@google.comsc_core::sc_object *Object::get_parent_object() const
19613123Sgabeblack@google.com{
19713123Sgabeblack@google.com    return parent;
19813123Sgabeblack@google.com}
19913123Sgabeblack@google.com
20013123Sgabeblack@google.combool
20113123Sgabeblack@google.comObject::add_attribute(sc_core::sc_attr_base &attr)
20213123Sgabeblack@google.com{
20313123Sgabeblack@google.com    return cltn.push_back(&attr);
20413123Sgabeblack@google.com}
20512841Sgabeblack@google.com
20612841Sgabeblack@google.comsc_core::sc_attr_base *
20712841Sgabeblack@google.comObject::get_attribute(const std::string &attr)
20812841Sgabeblack@google.com{
20912841Sgabeblack@google.com    return cltn[attr];
21012841Sgabeblack@google.com}
21112841Sgabeblack@google.com
21212841Sgabeblack@google.comsc_core::sc_attr_base *
21313123Sgabeblack@google.comObject::remove_attribute(const std::string &attr)
21413123Sgabeblack@google.com{
21513123Sgabeblack@google.com    return cltn.remove(attr);
21613123Sgabeblack@google.com}
21713274Sgabeblack@google.com
21813274Sgabeblack@google.comvoid
21913274Sgabeblack@google.comObject::remove_all_attributes()
22013123Sgabeblack@google.com{
22113123Sgabeblack@google.com    cltn.remove_all();
22213123Sgabeblack@google.com}
22313123Sgabeblack@google.com
22412841Sgabeblack@google.comint
22512841Sgabeblack@google.comObject::num_attributes() const
22612841Sgabeblack@google.com{
22712841Sgabeblack@google.com    return cltn.size();
22813143Sgabeblack@google.com}
22912841Sgabeblack@google.com
23013143Sgabeblack@google.comsc_core::sc_attr_cltn &
23112841Sgabeblack@google.comObject::attr_cltn()
23212841Sgabeblack@google.com{
23312841Sgabeblack@google.com    return cltn;
23412841Sgabeblack@google.com}
23512841Sgabeblack@google.com
23612841Sgabeblack@google.comconst sc_core::sc_attr_cltn &
237Object::attr_cltn() const
238{
239    return cltn;
240}
241
242sc_core::sc_simcontext *
243Object::simcontext() const
244{
245    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
246    return nullptr;
247}
248
249EventsIt
250Object::addChildEvent(sc_core::sc_event *e)
251{
252    return events.emplace(events.end(), e);
253}
254
255void
256Object::delChildEvent(sc_core::sc_event *e)
257{
258    EventsIt it = std::find(events.begin(), events.end(), e);
259    assert(it != events.end());
260    std::swap(*it, events.back());
261    events.pop_back();
262}
263
264std::string
265Object::pickUniqueName(std::string base)
266{
267    std::string seed = base;
268    while (!nameIsUnique(&children, &events, base))
269        base = ::sc_core::sc_gen_unique_name(seed.c_str());
270
271    return base;
272}
273
274std::string
275pickUniqueName(::sc_core::sc_object *parent, std::string base)
276{
277    if (parent)
278        return Object::getFromScObject(parent)->pickUniqueName(base);
279
280    std::string seed = base;
281    while (!nameIsUnique(&topLevelObjects, &topLevelEvents, base))
282        base = ::sc_core::sc_gen_unique_name(seed.c_str());
283
284    return base;
285}
286
287
288Objects topLevelObjects;
289Objects allObjects;
290
291const std::vector<sc_core::sc_object *> &
292getTopLevelScObjects()
293{
294    return topLevelObjects;
295}
296
297sc_core::sc_object *
298findObject(const char *name, const Objects &objects)
299{
300    ObjectsIt it = findObjectIn(allObjects, name);
301    return it == allObjects.end() ? nullptr : *it;
302}
303
304namespace
305{
306
307std::stack<sc_core::sc_object *> objParentStack;
308
309} // anonymous namespace
310
311sc_core::sc_object *
312pickParentObj()
313{
314    if (!objParentStack.empty())
315        return objParentStack.top();
316
317    Process *p = scheduler.current();
318    if (p)
319        return p;
320
321    return nullptr;
322}
323
324void pushParentObj(sc_core::sc_object *obj) { objParentStack.push(obj); }
325void popParentObj() { objParentStack.pop(); }
326
327} // namespace sc_gem5
328