event.cc revision 13243
12SN/A/*
24039Sbinkertn@umich.edu * 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 *
272665Ssaidi@eecs.umich.edu * Authors: Gabe Black
282665Ssaidi@eecs.umich.edu */
292665Ssaidi@eecs.umich.edu
302SN/A#include "systemc/core/event.hh"
312SN/A
328229Snate@binkert.org#include <algorithm>
332SN/A#include <cstring>
342SN/A#include <utility>
352SN/A
362SN/A#include "base/logging.hh"
3756SN/A#include "sim/core.hh"
384046Sbinkertn@umich.edu#include "systemc/core/module.hh"
394046Sbinkertn@umich.edu#include "systemc/core/scheduler.hh"
4056SN/A#include "systemc/ext/core/sc_main.hh"
412SN/A#include "systemc/ext/core/sc_module.hh"
422SN/A
432SN/Anamespace sc_gem5
442SN/A{
458232Snate@binkert.org
462SN/AEvent::Event(sc_core::sc_event *_sc_event) : Event(_sc_event, nullptr) {}
474074Sbinkertn@umich.edu
482SN/AEvent::Event(sc_core::sc_event *_sc_event, const char *_basename_cstr) :
492SN/A    _sc_event(_sc_event), _basename(_basename_cstr ? _basename_cstr : ""),
502SN/A    delayedNotify([this]() { this->notify(); }), _triggeredStamp(~0ULL)
512SN/A{
522SN/A    Module *p = currentModule();
532SN/A
542SN/A    if (_basename == "" && ::sc_core::sc_is_running())
55488SN/A        _basename = ::sc_core::sc_gen_unique_name("event");
564046Sbinkertn@umich.edu
574046Sbinkertn@umich.edu    if (p)
584046Sbinkertn@umich.edu        parent = p->obj()->sc_obj();
594046Sbinkertn@umich.edu    else if (scheduler.current())
604046Sbinkertn@umich.edu        parent = scheduler.current();
614046Sbinkertn@umich.edu    else
624046Sbinkertn@umich.edu        parent = nullptr;
634046Sbinkertn@umich.edu
644046Sbinkertn@umich.edu    std::string original_name = _basename;
654046Sbinkertn@umich.edu    _basename = pickUniqueName(parent, _basename);
668640SAli.Saidi@ARM.com
678640SAli.Saidi@ARM.com    if (parent) {
684046Sbinkertn@umich.edu        Object *obj = Object::getFromScObject(parent);
692SN/A        obj->addChildEvent(_sc_event);
701031SN/A    } else {
712SN/A        topLevelEvents.emplace(topLevelEvents.end(), _sc_event);
7210292SAndreas.Sandberg@ARM.com    }
7310292SAndreas.Sandberg@ARM.com
7410292SAndreas.Sandberg@ARM.com    std::string path = parent ? (std::string(parent->name()) + ".") : "";
754046Sbinkertn@umich.edu
764046Sbinkertn@umich.edu    if (original_name != "" && _basename != original_name) {
7710292SAndreas.Sandberg@ARM.com        std::string message = path + original_name +
782SN/A            ". Latter declaration will be renamed to " +
794046Sbinkertn@umich.edu            path + _basename;
802SN/A        SC_REPORT_WARNING("(W505) object already exists", message.c_str());
8110292SAndreas.Sandberg@ARM.com    }
8210292SAndreas.Sandberg@ARM.com
832SN/A    _name = path + _basename;
8410292SAndreas.Sandberg@ARM.com
8510292SAndreas.Sandberg@ARM.com    allEvents.emplace(allEvents.end(), _sc_event);
862SN/A
8710292SAndreas.Sandberg@ARM.com    // Determine if we're in the hierarchy (created once initialization starts
882SN/A    // means no).
892SN/A}
904046Sbinkertn@umich.edu
914046Sbinkertn@umich.eduEvent::~Event()
922SN/A{
9310292SAndreas.Sandberg@ARM.com    if (parent) {
9410292SAndreas.Sandberg@ARM.com        Object *obj = Object::getFromScObject(parent);
9510292SAndreas.Sandberg@ARM.com        obj->delChildEvent(_sc_event);
962SN/A    } else {
9710292SAndreas.Sandberg@ARM.com        EventsIt it = find(topLevelEvents.begin(), topLevelEvents.end(),
9810292SAndreas.Sandberg@ARM.com                           _sc_event);
9910292SAndreas.Sandberg@ARM.com        assert(it != topLevelEvents.end());
1002SN/A        std::swap(*it, topLevelEvents.back());
1014046Sbinkertn@umich.edu        topLevelEvents.pop_back();
1022SN/A    }
1032SN/A
1042SN/A    EventsIt it = findEvent(_name);
1052SN/A    std::swap(*it, allEvents.back());
1062SN/A    allEvents.pop_back();
1072SN/A
1082SN/A    if (delayedNotify.scheduled())
1092SN/A        scheduler.deschedule(&delayedNotify);
1102SN/A}
1112SN/A
1122SN/Aconst std::string &
1132SN/AEvent::name() const
1142SN/A{
1152SN/A    return _name;
1162SN/A}
1174046Sbinkertn@umich.edu
1182SN/Aconst std::string &
1192SN/AEvent::basename() const
1202SN/A{
1212SN/A    return _basename;
1222SN/A}
1232SN/A
1242SN/Abool
1252SN/AEvent::inHierarchy() const
1264046Sbinkertn@umich.edu{
1277811Ssteve.reinhardt@amd.com    return _name.length() != 0;
128}
129
130sc_core::sc_object *
131Event::getParentObject() const
132{
133    return parent;
134}
135
136void
137Event::notify(StaticSensitivities &senses)
138{
139    for (auto s: senses)
140        s->notify(this);
141}
142
143void
144Event::notify(DynamicSensitivities &senses)
145{
146    int size = senses.size();
147    int pos = 0;
148    while (pos < size) {
149        if (senses[pos]->notify(this))
150            senses[pos] = senses[--size];
151        else
152            pos++;
153    }
154    senses.resize(size);
155}
156
157void
158Event::notify()
159{
160    if (scheduler.inUpdate()) {
161        SC_REPORT_ERROR("(E521) immediate notification is not allowed "
162                "during update phase or elaboration", "");
163    }
164
165    // An immediate notification overrides any pending delayed notification.
166    if (delayedNotify.scheduled())
167        scheduler.deschedule(&delayedNotify);
168
169    _triggeredStamp = scheduler.changeStamp();
170
171    notify(staticSenseMethod);
172    notify(dynamicSenseMethod);
173    notify(staticSenseThread);
174    notify(dynamicSenseThread);
175}
176
177void
178Event::notify(const sc_core::sc_time &t)
179{
180    if (delayedNotify.scheduled()) {
181        if (scheduler.delayed(t) >= delayedNotify.when())
182            return;
183
184        scheduler.deschedule(&delayedNotify);
185    }
186    scheduler.schedule(&delayedNotify, t);
187}
188
189void
190Event::cancel()
191{
192    if (delayedNotify.scheduled())
193        scheduler.deschedule(&delayedNotify);
194}
195
196bool
197Event::triggered() const
198{
199    return _triggeredStamp == scheduler.changeStamp();
200}
201
202Events topLevelEvents;
203Events allEvents;
204
205EventsIt
206findEvent(const std::string &name)
207{
208    EventsIt it;
209    for (it = allEvents.begin(); it != allEvents.end(); it++)
210        if (!strcmp((*it)->name(), name.c_str()))
211            break;
212
213    return it;
214}
215
216} // namespace sc_gem5
217