object.cc revision 13179:7445c43d036b
12SN/A/*
22188SN/A * Copyright 2018 Google, Inc.
32SN/A *
42SN/A * Redistribution and use in source and binary forms, with or without
52SN/A * modification, are permitted provided that the following conditions are
62SN/A * met: redistributions of source code must retain the above copyright
72SN/A * notice, this list of conditions and the following disclaimer;
82SN/A * redistributions in binary form must reproduce the above copyright
92SN/A * notice, this list of conditions and the following disclaimer in the
102SN/A * documentation and/or other materials provided with the distribution;
112SN/A * neither the name of the copyright holders nor the names of its
122SN/A * contributors may be used to endorse or promote products derived from
132SN/A * this software without specific prior written permission.
142SN/A *
152SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262SN/A *
272665SN/A * Authors: Gabe Black
282665SN/A */
292665SN/A
302665SN/A#include "systemc/core/object.hh"
312665SN/A
322SN/A#include <algorithm>
332SN/A
342SN/A#include "base/logging.hh"
352SN/A#include "systemc/core/event.hh"
362465SN/A#include "systemc/core/module.hh"
377680Sgblack@eecs.umich.edu#include "systemc/core/scheduler.hh"
386658Snate@binkert.org#include "systemc/ext/core/sc_module.hh"
391717SN/A
402683Sktlim@umich.edunamespace sc_gem5
412680SN/A{
425529Snate@binkert.org
432SN/Anamespace
441858SN/A{
453565Sgblack@eecs.umich.edu
465529Snate@binkert.orgObjectsIt
471917SN/AfindObjectIn(Objects &objects, const std::string &name)
481070SN/A{
491917SN/A    ObjectsIt it;
502188SN/A    for (it = objects.begin(); it != objects.end(); it++)
511917SN/A        if (!strcmp((*it)->name(), name.c_str()))
522290SN/A            break;
531070SN/A
541917SN/A    return it;
552SN/A}
565529Snate@binkert.org
57360SN/Avoid
582519SN/AaddObject(Objects *objects, sc_core::sc_object *object)
592SN/A{
602SN/A    objects->emplace(objects->end(), object);
612SN/A}
622SN/A
632SN/Avoid
641858SN/ApopObject(Objects *objects, const std::string &name)
652683Sktlim@umich.edu{
666022Sgblack@eecs.umich.edu    ObjectsIt it = findObjectIn(*objects, name);
672683Sktlim@umich.edu    assert(it != objects->end());
686324Sgblack@eecs.umich.edu    std::swap(objects->back(), *it);
696324Sgblack@eecs.umich.edu    objects->pop_back();
702521SN/A}
712SN/A
722683Sktlim@umich.edubool
732190SN/AnameIsUnique(Objects *objects, Events *events, const std::string &name)
742680SN/A{
752290SN/A    for (auto obj: *objects)
766316Sgblack@eecs.umich.edu        if (!strcmp(obj->basename(), name.c_str()))
771917SN/A            return false;
785529Snate@binkert.org    for (auto event: *events)
791982SN/A        if (!strcmp(event->basename(), name.c_str()))
801917SN/A            return false;
812683Sktlim@umich.edu    return true;
822683Sktlim@umich.edu}
831917SN/A
841917SN/A} // anonymous namespace
851917SN/A
861917SN/AObject::Object(sc_core::sc_object *_sc_obj) : Object(_sc_obj, nullptr) {}
871917SN/A
881917SN/AObject::Object(sc_core::sc_object *_sc_obj, const char *obj_name) :
891917SN/A    _sc_obj(_sc_obj), _basename(obj_name ? obj_name : ""), parent(nullptr)
901917SN/A{
912521SN/A    if (_basename == "")
925482Snate@binkert.org        _basename = ::sc_core::sc_gen_unique_name("object");
933548Sgblack@eecs.umich.edu
942SN/A    Module *p = currentModule();
952SN/A    if (!p)
964997Sgblack@eecs.umich.edu        p = callbackModule();
976331Sgblack@eecs.umich.edu
986331Sgblack@eecs.umich.edu    Module *n = newModule();
994997Sgblack@eecs.umich.edu    if (n) {
1002SN/A        // We are a module in the process of being constructed.
1016316Sgblack@eecs.umich.edu        n->finish(this);
1022683Sktlim@umich.edu    }
1032SN/A
1042190SN/A    if (p) {
1052862Sktlim@umich.edu        // We're "within" a parent module, ie we're being created while its
1062862Sktlim@umich.edu        // constructor or end_of_elaboration callback is running.
1072864Sktlim@umich.edu        parent = p->obj()->_sc_obj;
1082862Sktlim@umich.edu    } else if (scheduler.current()) {
1095712Shsul@eecs.umich.edu        // Our parent is the currently running process.
1102862Sktlim@umich.edu        parent = scheduler.current();
1116331Sgblack@eecs.umich.edu    }
1122862Sktlim@umich.edu
1132190SN/A    std::string original_name = _basename;
1142683Sktlim@umich.edu    _basename = sc_gem5::pickUniqueName(parent, original_name);
1152190SN/A
1162190SN/A    if (parent)
1172683Sktlim@umich.edu        addObject(&parent->_gem5_object->children, _sc_obj);
1181070SN/A    else
1193486Sktlim@umich.edu        addObject(&topLevelObjects, _sc_obj);
1203486Sktlim@umich.edu
1213486Sktlim@umich.edu    addObject(&allObjects, _sc_obj);
1223486Sktlim@umich.edu
1232680SN/A    sc_core::sc_object *sc_p = parent;
1241070SN/A    std::string path = "";
1251070SN/A    while (sc_p) {
1261917SN/A        path = std::string(sc_p->basename()) + std::string(".") + path;
1272683Sktlim@umich.edu        sc_p = sc_p->get_parent_object();
128180SN/A    }
129180SN/A
1301858SN/A    if (_basename != original_name) {
1312235SN/A        std::string message = path + original_name +
132180SN/A            ". Latter declaration will be renamed to " +
1332235SN/A            path + _basename;
134180SN/A        SC_REPORT_WARNING("(W505) object already exists", message.c_str());
135180SN/A    }
1362862Sktlim@umich.edu    _name = path + _basename;
1372862Sktlim@umich.edu}
1382313SN/A
1392313SN/AObject::Object(sc_core::sc_object *_sc_obj, const Object &arg) :
1402680SN/A    Object(_sc_obj, arg._basename.c_str())
1412313SN/A{}
1422680SN/A
1432313SN/AObject &
1442313SN/AObject::operator = (const Object &)
1452680SN/A{
1462313SN/A    return *this;
1472361SN/A}
1483548Sgblack@eecs.umich.edu
1492361SN/AObject::~Object()
1502361SN/A{
1512361SN/A    // Promote all children to be top level objects.
1522235SN/A    for (auto child: children) {
153180SN/A        addObject(&topLevelObjects, child);
154180SN/A        child->_gem5_object->parent = nullptr;
155180SN/A    }
1566029Ssteve.reinhardt@amd.com    children.clear();
157180SN/A
158180SN/A    if (parent)
1592SN/A        popObject(&parent->_gem5_object->children, _name);
1602864Sktlim@umich.edu    else
1612864Sktlim@umich.edu        popObject(&topLevelObjects, _name);
1622864Sktlim@umich.edu    popObject(&allObjects, _name);
1632864Sktlim@umich.edu}
1642864Sktlim@umich.edu
1652864Sktlim@umich.educonst char *
1662864Sktlim@umich.eduObject::name() const
1672864Sktlim@umich.edu{
1682864Sktlim@umich.edu    return _name.c_str();
1693548Sgblack@eecs.umich.edu}
1702864Sktlim@umich.edu
1712864Sktlim@umich.educonst char *
1722864Sktlim@umich.eduObject::basename() const
1732864Sktlim@umich.edu{
1742864Sktlim@umich.edu    return _basename.c_str();
1752864Sktlim@umich.edu}
1762864Sktlim@umich.edu
1772862Sktlim@umich.eduvoid
1782862Sktlim@umich.eduObject::print(std::ostream &out) const
1792862Sktlim@umich.edu{
1802862Sktlim@umich.edu    out << name();
1812862Sktlim@umich.edu}
1822862Sktlim@umich.edu
1832862Sktlim@umich.eduvoid
1842862Sktlim@umich.eduObject::dump(std::ostream &out) const
1855714Shsul@eecs.umich.edu{
1865715Shsul@eecs.umich.edu    out << "name = " << name() << "\n";
1875714Shsul@eecs.umich.edu    out << "kind = " << _sc_obj->kind() << "\n";
1882862Sktlim@umich.edu}
1892862Sktlim@umich.edu
1902862Sktlim@umich.educonst std::vector<sc_core::sc_object *> &
1912683Sktlim@umich.eduObject::get_child_objects() const
192217SN/A{
1932862Sktlim@umich.edu    return children;
1946315Sgblack@eecs.umich.edu}
1956316Sgblack@eecs.umich.edu
1967720Sgblack@eecs.umich.educonst std::vector<sc_core::sc_event *> &
197223SN/AObject::get_child_events() const
1986677SBrad.Beckmann@amd.com{
1996677SBrad.Beckmann@amd.com    return events;
2006677SBrad.Beckmann@amd.com}
2016677SBrad.Beckmann@amd.com
2026678Sgblack@eecs.umich.edusc_core::sc_object *Object::get_parent_object() const
203217SN/A{
204217SN/A    return parent;
205217SN/A}
206217SN/A
2072683Sktlim@umich.edubool
208217SN/AObject::add_attribute(sc_core::sc_attr_base &attr)
2092862Sktlim@umich.edu{
2106315Sgblack@eecs.umich.edu    return cltn.push_back(&attr);
2116316Sgblack@eecs.umich.edu}
2127720Sgblack@eecs.umich.edu
213223SN/Asc_core::sc_attr_base *
2146677SBrad.Beckmann@amd.comObject::get_attribute(const std::string &attr)
2156677SBrad.Beckmann@amd.com{
2166677SBrad.Beckmann@amd.com    return cltn[attr];
2176677SBrad.Beckmann@amd.com}
2186678Sgblack@eecs.umich.edu
219217SN/Asc_core::sc_attr_base *
220217SN/AObject::remove_attribute(const std::string &attr)
2212683Sktlim@umich.edu{
2222683Sktlim@umich.edu    return cltn.remove(attr);
2232683Sktlim@umich.edu}
2242683Sktlim@umich.edu
2252683Sktlim@umich.eduvoid
2262683Sktlim@umich.eduObject::remove_all_attributes()
2272683Sktlim@umich.edu{
2282683Sktlim@umich.edu    cltn.remove_all();
229217SN/A}
230217SN/A
2312683Sktlim@umich.eduint
2322SN/AObject::num_attributes() const
2332680SN/A{
2342SN/A    return cltn.size();
2352SN/A}
2362188SN/A
2372188SN/Asc_core::sc_attr_cltn &
2384400Srdreslin@umich.eduObject::attr_cltn()
2395715Shsul@eecs.umich.edu{
2405543Ssaidi@eecs.umich.edu    return cltn;
2414400Srdreslin@umich.edu}
2422290SN/A
2432680SN/Aconst sc_core::sc_attr_cltn &
2442290SN/AObject::attr_cltn() const
2452290SN/A{
2465715Shsul@eecs.umich.edu    return cltn;
247393SN/A}
248393SN/A
249393SN/Asc_core::sc_simcontext *
2502683Sktlim@umich.eduObject::simcontext() const
251393SN/A{
2522680SN/A    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
253393SN/A    return nullptr;
254393SN/A}
2552188SN/A
2562188SN/AEventsIt
2572188SN/AObject::addChildEvent(sc_core::sc_event *e)
2581858SN/A{
2592SN/A    return events.emplace(events.end(), e);
2605704Snate@binkert.org}
2612680SN/A
2622SN/Avoid
2632SN/AObject::delChildEvent(sc_core::sc_event *e)
2642SN/A{
2652188SN/A    EventsIt it = std::find(events.begin(), events.end(), e);
2662680SN/A    assert(it != events.end());
2675715Shsul@eecs.umich.edu    std::swap(*it, events.back());
2682SN/A    events.pop_back();
2692SN/A}
270393SN/A
271393SN/Astd::string
2722683Sktlim@umich.eduObject::pickUniqueName(std::string base)
273393SN/A{
2742680SN/A    std::string seed = base;
275393SN/A    while (!nameIsUnique(&children, &events, base))
276393SN/A        base = ::sc_core::sc_gen_unique_name(seed.c_str());
2772680SN/A
2785715Shsul@eecs.umich.edu    return base;
279393SN/A}
280393SN/A
281393SN/Astd::string
282393SN/ApickUniqueName(::sc_core::sc_object *parent, std::string base)
2832683Sktlim@umich.edu{
2842SN/A    if (parent)
2852330SN/A        return Object::getFromScObject(parent)->pickUniqueName(base);
2862341SN/A
2872341SN/A    std::string seed = base;
2882330SN/A    while (!nameIsUnique(&topLevelObjects, &topLevelEvents, base))
2892SN/A        base = ::sc_core::sc_gen_unique_name(seed.c_str());
290716SN/A
291716SN/A    return base;
2922683Sktlim@umich.edu}
2932190SN/A
2942680SN/A
2952190SN/AObjects topLevelObjects;
2962190SN/AObjects 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