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