process.cc revision 12996
12810SN/A/* 22810SN/A * Copyright 2018 Google, Inc. 32810SN/A * 42810SN/A * Redistribution and use in source and binary forms, with or without 52810SN/A * modification, are permitted provided that the following conditions are 62810SN/A * met: redistributions of source code must retain the above copyright 72810SN/A * notice, this list of conditions and the following disclaimer; 82810SN/A * redistributions in binary form must reproduce the above copyright 92810SN/A * notice, this list of conditions and the following disclaimer in the 102810SN/A * documentation and/or other materials provided with the distribution; 112810SN/A * neither the name of the copyright holders nor the names of its 122810SN/A * contributors may be used to endorse or promote products derived from 132810SN/A * this software without specific prior written permission. 142810SN/A * 152810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262810SN/A * 272810SN/A * Authors: Gabe Black 282810SN/A */ 294458SN/A 304458SN/A#include "systemc/core/process.hh" 312810SN/A 322810SN/A#include "base/logging.hh" 332810SN/A#include "systemc/core/event.hh" 342810SN/A#include "systemc/core/scheduler.hh" 352810SN/A 362810SN/Anamespace sc_gem5 372810SN/A{ 382810SN/A 392810SN/ASensitivityTimeout::SensitivityTimeout(Process *p, ::sc_core::sc_time t) : 402810SN/A Sensitivity(p), timeoutEvent(this), time(t) 417676Snate@binkert.org{ 427676Snate@binkert.org Tick when = scheduler.getCurTick() + time.value(); 437676Snate@binkert.org scheduler.schedule(&timeoutEvent, when); 442810SN/A} 452810SN/A 462825SN/ASensitivityTimeout::~SensitivityTimeout() 472810SN/A{ 482810SN/A if (timeoutEvent.scheduled()) 496215Snate@binkert.org scheduler.deschedule(&timeoutEvent); 508232Snate@binkert.org} 518232Snate@binkert.org 525338Sstever@gmail.comvoid 532810SN/ASensitivityTimeout::timeout() 542810SN/A{ 558229Snate@binkert.org scheduler.eventHappened(); 564626SN/A notify(); 575034SN/A} 582811SN/A 598786Sgblack@eecs.umich.eduSensitivityEvent::SensitivityEvent( 604626SN/A Process *p, const ::sc_core::sc_event *e) : Sensitivity(p), event(e) 618833Sdam.sunwoo@arm.com{ 622810SN/A Event::getFromScEvent(event)->addSensitivity(this); 633194SN/A} 642810SN/A 652810SN/ASensitivityEvent::~SensitivityEvent() 662810SN/A{ 672810SN/A Event::getFromScEvent(event)->delSensitivity(this); 682810SN/A} 694628SN/A 704628SN/ASensitivityEventAndList::SensitivityEventAndList( 714628SN/A Process *p, const ::sc_core::sc_event_and_list *list) : 724628SN/A Sensitivity(p), list(list), count(0) 734628SN/A{ 744628SN/A for (auto e: list->events) 754628SN/A Event::getFromScEvent(e)->addSensitivity(this); 764628SN/A} 778737Skoansin.tan@gmail.com 784628SN/ASensitivityEventAndList::~SensitivityEventAndList() 794628SN/A{ 804628SN/A for (auto e: list->events) 814628SN/A Event::getFromScEvent(e)->delSensitivity(this); 824628SN/A} 834628SN/A 844628SN/Avoid 854628SN/ASensitivityEventAndList::notifyWork(Event *e) 864628SN/A{ 874628SN/A e->delSensitivity(this); 884628SN/A count++; 894628SN/A if (count == list->events.size()) 904628SN/A process->satisfySensitivity(this); 914628SN/A} 924628SN/A 934628SN/ASensitivityEventOrList::SensitivityEventOrList( 944628SN/A Process *p, const ::sc_core::sc_event_or_list *list) : 954628SN/A Sensitivity(p), list(list) 964628SN/A{ 974628SN/A for (auto e: list->events) 988737Skoansin.tan@gmail.com Event::getFromScEvent(e)->addSensitivity(this); 994628SN/A} 1004626SN/A 1012810SN/ASensitivityEventOrList::~SensitivityEventOrList() 1022844SN/A{ 1032810SN/A for (auto e: list->events) 1042810SN/A Event::getFromScEvent(e)->delSensitivity(this); 1053738SN/A} 1064965SN/A 1076122SSteve.Reinhardt@amd.com 1084458SN/Aclass UnwindExceptionReset : public ::sc_core::sc_unwind_exception 1096227Snate@binkert.org{ 1102810SN/A public: 1114458SN/A UnwindExceptionReset() { _isReset = true; } 1123013SN/A}; 1134666SN/A 1144666SN/Aclass UnwindExceptionKill : public ::sc_core::sc_unwind_exception 1154666SN/A{ 1165314SN/A public: 1175314SN/A UnwindExceptionKill() {} 1182811SN/A}; 1192810SN/A 1202810SN/Atemplate <typename T> 1212810SN/Astruct BuiltinExceptionWrapper : public ExceptionWrapperBase 1222810SN/A{ 1235314SN/A public: 1243606SN/A T t; 1252810SN/A void throw_it() override { throw t; } 1262810SN/A}; 1272897SN/A 1282897SN/ABuiltinExceptionWrapper<UnwindExceptionReset> resetException; 1294458SN/ABuiltinExceptionWrapper<UnwindExceptionKill> killException; 1304458SN/A 1314888SN/A 1324666SN/Avoid 1334666SN/AProcess::forEachKid(const std::function<void(Process *)> &work) 1344458SN/A{ 1354458SN/A for (auto &kid: get_child_objects()) { 1364458SN/A Process *p_kid = dynamic_cast<Process *>(kid); 1374626SN/A if (p_kid) 1384626SN/A work(p_kid); 1394626SN/A } 1402811SN/A} 1412810SN/A 1423338SN/Avoid 1433738SN/AProcess::suspend(bool inc_kids) 1443338SN/A{ 1454626SN/A if (inc_kids) 1464626SN/A forEachKid([](Process *p) { p->suspend(true); }); 1474626SN/A 1484626SN/A if (!_suspended) { 1494626SN/A _suspended = true; 1504626SN/A _suspendedReady = false; 1514626SN/A } 1524626SN/A 1534628SN/A if (procKind() != ::sc_core::SC_METHOD_PROC_ && 1544628SN/A scheduler.current() == this) { 1554628SN/A scheduler.yield(); 1564666SN/A } 1574628SN/A} 1584628SN/A 1594628SN/Avoid 1604628SN/AProcess::resume(bool inc_kids) 1614628SN/A{ 1624628SN/A if (inc_kids) 1634628SN/A forEachKid([](Process *p) { p->resume(true); }); 1644628SN/A 1654628SN/A if (_suspended) { 1664628SN/A _suspended = false; 1674628SN/A if (_suspendedReady) 1684628SN/A ready(); 1697667Ssteve.reinhardt@amd.com _suspendedReady = false; 1704628SN/A } 1714628SN/A} 1724628SN/A 1737667Ssteve.reinhardt@amd.comvoid 1744628SN/AProcess::disable(bool inc_kids) 1754628SN/A{ 1764628SN/A if (inc_kids) 1774628SN/A forEachKid([](Process *p) { p->disable(true); }); 1784628SN/A 1794626SN/A _disabled = true; 1806227Snate@binkert.org} 1814626SN/A 1824630SN/Avoid 1834630SN/AProcess::enable(bool inc_kids) 1844630SN/A{ 1854630SN/A 1864630SN/A if (inc_kids) 1874626SN/A forEachKid([](Process *p) { p->enable(true); }); 1884626SN/A 1894626SN/A _disabled = false; 1906122SSteve.Reinhardt@amd.com} 1916122SSteve.Reinhardt@amd.com 1924626SN/Avoid 1938134SAli.Saidi@ARM.comProcess::kill(bool inc_kids) 1948134SAli.Saidi@ARM.com{ 1958134SAli.Saidi@ARM.com // Propogate the kill to our children no matter what happens to us. 1968134SAli.Saidi@ARM.com if (inc_kids) 1978134SAli.Saidi@ARM.com forEachKid([](Process *p) { p->kill(true); }); 1982810SN/A 1992810SN/A // If we're in the middle of unwinding, ignore the kill request. 2002810SN/A if (_isUnwinding) 2012810SN/A return; 2022810SN/A 2032810SN/A // Update our state. 2046122SSteve.Reinhardt@amd.com _terminated = true; 2056122SSteve.Reinhardt@amd.com _isUnwinding = true; 2066122SSteve.Reinhardt@amd.com _suspendedReady = false; 2072810SN/A _suspended = false; 2082810SN/A _syncReset = false; 2092810SN/A 2104626SN/A // Inject the kill exception into this process. 2114626SN/A injectException(killException); 2122810SN/A 2132810SN/A _terminatedEvent.notify(); 2142810SN/A} 2152810SN/A 2163503SN/Avoid 2173503SN/AProcess::reset(bool inc_kids) 2183503SN/A{ 2196122SSteve.Reinhardt@amd.com // Propogate the reset to our children no matter what happens to us. 2206122SSteve.Reinhardt@amd.com if (inc_kids) 2216122SSteve.Reinhardt@amd.com forEachKid([](Process *p) { p->reset(true); }); 2226122SSteve.Reinhardt@amd.com 2236122SSteve.Reinhardt@amd.com // If we're in the middle of unwinding, ignore the reset request. 2248833Sdam.sunwoo@arm.com if (_isUnwinding) 2258833Sdam.sunwoo@arm.com return; 2268833Sdam.sunwoo@arm.com 2276978SLisa.Hsu@amd.com // Update our state. 2282810SN/A _isUnwinding = true; 2292810SN/A 2302810SN/A // Inject the reset exception into this process. 2312810SN/A injectException(resetException); 2322810SN/A 2332810SN/A _resetEvent.notify(); 2342810SN/A} 2355999Snate@binkert.org 2362810SN/Avoid 2372810SN/AProcess::throw_it(ExceptionWrapperBase &exc, bool inc_kids) 2382810SN/A{ 2392810SN/A if (inc_kids) 2402810SN/A forEachKid([&exc](Process *p) { p->throw_it(exc, true); }); 2412810SN/A} 2425999Snate@binkert.org 2432810SN/Avoid 2442810SN/AProcess::injectException(ExceptionWrapperBase &exc) 2452810SN/A{ 2462810SN/A excWrapper = &exc; 2472810SN/A scheduler.runNow(this); 2482810SN/A}; 2492810SN/A 2502810SN/Avoid 2512810SN/AProcess::syncResetOn(bool inc_kids) 2525999Snate@binkert.org{ 2532810SN/A if (inc_kids) 2542810SN/A forEachKid([](Process *p) { p->syncResetOn(true); }); 2552810SN/A 2562810SN/A _syncReset = true; 2572810SN/A} 2582810SN/A 2594022SN/Avoid 2602810SN/AProcess::syncResetOff(bool inc_kids) 2612810SN/A{ 2622810SN/A if (inc_kids) 2632810SN/A forEachKid([](Process *p) { p->syncResetOff(true); }); 2642810SN/A 2652810SN/A _syncReset = false; 2664022SN/A} 2672810SN/A 2682810SN/Avoid 2692810SN/AProcess::dontInitialize() 2702810SN/A{ 2712810SN/A scheduler.dontInitialize(this); 2722810SN/A} 2734022SN/A 2742810SN/Avoid 2752810SN/AProcess::finalize() 2762810SN/A{ 2772810SN/A for (auto &s: pendingStaticSensitivities) { 2782810SN/A s->finalize(staticSensitivities); 2792810SN/A delete s; 2805999Snate@binkert.org s = nullptr; 2812810SN/A } 2825999Snate@binkert.org pendingStaticSensitivities.clear(); 2832810SN/A}; 2842810SN/A 2852810SN/Avoid 2862810SN/AProcess::run() 2872810SN/A{ 2885999Snate@binkert.org bool reset; 2892810SN/A do { 2902810SN/A reset = false; 2915999Snate@binkert.org try { 2922810SN/A func->call(); 2934626SN/A } catch(const ::sc_core::sc_unwind_exception &exc) { 2945999Snate@binkert.org reset = exc.is_reset(); 2954626SN/A _isUnwinding = false; 2964626SN/A } 2975999Snate@binkert.org } while (reset); 2984626SN/A _terminated = true; 2994626SN/A} 3004626SN/A 3014626SN/Avoid 3024626SN/AProcess::addStatic(PendingSensitivity *s) 3034626SN/A{ 3045999Snate@binkert.org pendingStaticSensitivities.push_back(s); 3054626SN/A} 3064626SN/A 3074626SN/Avoid 3084626SN/AProcess::setDynamic(Sensitivity *s) 3094626SN/A{ 3104626SN/A delete dynamicSensitivity; 3115999Snate@binkert.org dynamicSensitivity = s; 3124626SN/A} 3134626SN/A 3144626SN/Avoid 3154626SN/AProcess::satisfySensitivity(Sensitivity *s) 3165999Snate@binkert.org{ 3174626SN/A // If there's a dynamic sensitivity and this wasn't it, ignore. 3184626SN/A if (dynamicSensitivity && dynamicSensitivity != s) 3194626SN/A return; 3204626SN/A 3214626SN/A setDynamic(nullptr); 3224626SN/A ready(); 3235999Snate@binkert.org} 3244626SN/A 3254626SN/Avoid 3264626SN/AProcess::ready() 3277461Snate@binkert.org{ 3284626SN/A if (disabled()) 3294626SN/A return; 3304626SN/A if (suspended()) 3314626SN/A _suspendedReady = true; 3324626SN/A else 3334626SN/A scheduler.ready(this); 3347461Snate@binkert.org} 3354626SN/A 3364626SN/AProcess::Process(const char *name, ProcessFuncWrapper *func, 3374626SN/A bool _dynamic, bool needs_start) : 3384626SN/A ::sc_core::sc_object(name), excWrapper(nullptr), func(func), 3394626SN/A _needsStart(needs_start), _dynamic(_dynamic), _isUnwinding(false), 3404626SN/A _terminated(false), _suspended(false), _disabled(false), 3414626SN/A _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize), 3424626SN/A dynamicSensitivity(nullptr) 3434626SN/A{ 3444626SN/A _newest = this; 3454626SN/A} 3464626SN/A 3474626SN/AProcess *Process::_newest; 3484626SN/A 3494626SN/Avoid 3504626SN/Athrow_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids) 3514626SN/A{ 3524626SN/A p->throw_it(exc, inc_kids); 3534626SN/A} 3544626SN/A 3554626SN/A} // namespace sc_gem5 3565999Snate@binkert.org