event.cc revision 13317:36c574a4036e
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/event.hh" 31 32#include <algorithm> 33#include <cstring> 34#include <utility> 35 36#include "base/logging.hh" 37#include "sim/core.hh" 38#include "systemc/core/module.hh" 39#include "systemc/core/scheduler.hh" 40#include "systemc/ext/core/messages.hh" 41#include "systemc/ext/core/sc_main.hh" 42#include "systemc/ext/core/sc_module.hh" 43 44namespace sc_gem5 45{ 46 47Event::Event(sc_core::sc_event *_sc_event, bool internal) : 48 Event(_sc_event, nullptr, internal) 49{} 50 51Event::Event(sc_core::sc_event *_sc_event, const char *_basename_cstr, 52 bool internal) : 53 _sc_event(_sc_event), _basename(_basename_cstr ? _basename_cstr : ""), 54 _inHierarchy(!internal), delayedNotify([this]() { this->notify(); }), 55 _triggeredStamp(~0ULL) 56{ 57 if (_basename == "" && ::sc_core::sc_is_running()) 58 _basename = ::sc_core::sc_gen_unique_name("event"); 59 60 parent = internal ? nullptr : pickParentObj(); 61 62 if (internal) { 63 _basename = globalNameGen.gen(_basename); 64 _name = _basename; 65 } else { 66 std::string original_name = _basename; 67 _basename = pickUniqueName(parent, _basename); 68 69 if (parent) { 70 Object *obj = Object::getFromScObject(parent); 71 obj->addChildEvent(_sc_event); 72 } else { 73 topLevelEvents.emplace(topLevelEvents.end(), _sc_event); 74 } 75 76 std::string path = parent ? (std::string(parent->name()) + ".") : ""; 77 78 if (original_name != "" && _basename != original_name) { 79 std::string message = path + original_name + 80 ". Latter declaration will be renamed to " + 81 path + _basename; 82 SC_REPORT_WARNING(sc_core::SC_ID_INSTANCE_EXISTS_, 83 message.c_str()); 84 } 85 86 _name = path + _basename; 87 } 88 89 allEvents.emplace(allEvents.end(), _sc_event); 90 91 // Determine if we're in the hierarchy (created once initialization starts 92 // means no). 93} 94 95Event::~Event() 96{ 97 if (parent) { 98 Object *obj = Object::getFromScObject(parent); 99 obj->delChildEvent(_sc_event); 100 } else if (inHierarchy()) { 101 EventsIt it = find(topLevelEvents.begin(), topLevelEvents.end(), 102 _sc_event); 103 assert(it != topLevelEvents.end()); 104 std::swap(*it, topLevelEvents.back()); 105 topLevelEvents.pop_back(); 106 } 107 108 EventsIt it = findEvent(_name); 109 std::swap(*it, allEvents.back()); 110 allEvents.pop_back(); 111 112 if (delayedNotify.scheduled()) 113 scheduler.deschedule(&delayedNotify); 114} 115 116const std::string & 117Event::name() const 118{ 119 return _name; 120} 121 122const std::string & 123Event::basename() const 124{ 125 return _basename; 126} 127 128bool 129Event::inHierarchy() const 130{ 131 return _inHierarchy; 132} 133 134sc_core::sc_object * 135Event::getParentObject() const 136{ 137 return parent; 138} 139 140void 141Event::notify(StaticSensitivities &senses) 142{ 143 for (auto s: senses) 144 s->notify(this); 145} 146 147void 148Event::notify(DynamicSensitivities &senses) 149{ 150 int size = senses.size(); 151 int pos = 0; 152 while (pos < size) { 153 if (senses[pos]->notify(this)) 154 senses[pos] = senses[--size]; 155 else 156 pos++; 157 } 158 senses.resize(size); 159} 160 161void 162Event::notify() 163{ 164 if (scheduler.inUpdate()) 165 SC_REPORT_ERROR(sc_core::SC_ID_IMMEDIATE_NOTIFICATION_, ""); 166 167 // An immediate notification overrides any pending delayed notification. 168 if (delayedNotify.scheduled()) 169 scheduler.deschedule(&delayedNotify); 170 171 _triggeredStamp = scheduler.changeStamp(); 172 notify(staticSenseMethod); 173 notify(dynamicSenseMethod); 174 notify(staticSenseThread); 175 notify(dynamicSenseThread); 176} 177 178void 179Event::notify(const sc_core::sc_time &t) 180{ 181 if (delayedNotify.scheduled()) { 182 if (scheduler.delayed(t) >= delayedNotify.when()) 183 return; 184 185 scheduler.deschedule(&delayedNotify); 186 } 187 scheduler.schedule(&delayedNotify, t); 188} 189 190void 191Event::notifyDelayed(const sc_core::sc_time &t) 192{ 193 if (delayedNotify.scheduled()) 194 SC_REPORT_ERROR(sc_core::SC_ID_NOTIFY_DELAYED_, ""); 195 notify(t); 196} 197 198void 199Event::cancel() 200{ 201 if (delayedNotify.scheduled()) 202 scheduler.deschedule(&delayedNotify); 203} 204 205bool 206Event::triggered() const 207{ 208 return _triggeredStamp == scheduler.changeStamp(); 209} 210 211void 212Event::clearParent() 213{ 214 if (!parent) 215 return; 216 Object::getFromScObject(parent)->delChildEvent(sc_event()); 217 parent = nullptr; 218 topLevelEvents.emplace(topLevelEvents.end(), sc_event()); 219} 220 221Events topLevelEvents; 222Events allEvents; 223 224EventsIt 225findEvent(const std::string &name) 226{ 227 EventsIt it; 228 for (it = allEvents.begin(); it != allEvents.end(); it++) 229 if (!strcmp((*it)->name(), name.c_str())) 230 break; 231 232 return it; 233} 234 235} // namespace sc_gem5 236