scheduler.cc revision 13312
112953Sgabeblack@google.com/* 212953Sgabeblack@google.com * Copyright 2018 Google, Inc. 312953Sgabeblack@google.com * 412953Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512953Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612953Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712953Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812953Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912953Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012953Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112953Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212953Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312953Sgabeblack@google.com * this software without specific prior written permission. 1412953Sgabeblack@google.com * 1512953Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612953Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712953Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812953Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912953Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012953Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112953Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212953Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312953Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412953Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512953Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612953Sgabeblack@google.com * 2712953Sgabeblack@google.com * Authors: Gabe Black 2812953Sgabeblack@google.com */ 2912953Sgabeblack@google.com 3012953Sgabeblack@google.com#include "systemc/core/scheduler.hh" 3112953Sgabeblack@google.com 3212953Sgabeblack@google.com#include "base/fiber.hh" 3312954Sgabeblack@google.com#include "base/logging.hh" 3412954Sgabeblack@google.com#include "sim/eventq.hh" 3512982Sgabeblack@google.com#include "systemc/core/kernel.hh" 3612982Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh" 3713182Sgabeblack@google.com#include "systemc/ext/utils/sc_report.hh" 3813182Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh" 3913312Sgabeblack@google.com#include "systemc/utils/report.hh" 4013245Sgabeblack@google.com#include "systemc/utils/tracefile.hh" 4112953Sgabeblack@google.com 4212953Sgabeblack@google.comnamespace sc_gem5 4312953Sgabeblack@google.com{ 4412953Sgabeblack@google.com 4512954Sgabeblack@google.comScheduler::Scheduler() : 4612962Sgabeblack@google.com eq(nullptr), readyEvent(this, false, ReadyPriority), 4712961Sgabeblack@google.com pauseEvent(this, false, PausePriority), 4812961Sgabeblack@google.com stopEvent(this, false, StopPriority), 4913182Sgabeblack@google.com scMain(nullptr), _throwToScMain(nullptr), 5012987Sgabeblack@google.com starvationEvent(this, false, StarvationPriority), 5113203Sgabeblack@google.com _elaborationDone(false), _started(false), _stopNow(false), 5213203Sgabeblack@google.com _status(StatusOther), maxTickEvent(this, false, MaxTickPriority), 5313245Sgabeblack@google.com timeAdvancesEvent(this, false, TimeAdvancesPriority), _numCycles(0), 5413245Sgabeblack@google.com _changeStamp(0), _current(nullptr), initDone(false), runOnce(false) 5512954Sgabeblack@google.com{} 5612953Sgabeblack@google.com 5713072Sgabeblack@google.comScheduler::~Scheduler() 5813072Sgabeblack@google.com{ 5913072Sgabeblack@google.com // Clear out everything that belongs to us to make sure nobody tries to 6013072Sgabeblack@google.com // clear themselves out after the scheduler goes away. 6113076Sgabeblack@google.com clear(); 6213076Sgabeblack@google.com} 6313072Sgabeblack@google.com 6413076Sgabeblack@google.comvoid 6513076Sgabeblack@google.comScheduler::clear() 6613076Sgabeblack@google.com{ 6713072Sgabeblack@google.com // Delta notifications. 6813144Sgabeblack@google.com while (!deltas.empty()) 6913144Sgabeblack@google.com deltas.front()->deschedule(); 7013072Sgabeblack@google.com 7113072Sgabeblack@google.com // Timed notifications. 7213076Sgabeblack@google.com for (auto &tsp: timeSlots) { 7313076Sgabeblack@google.com TimeSlot *&ts = tsp.second; 7413144Sgabeblack@google.com while (!ts->events.empty()) 7513144Sgabeblack@google.com ts->events.front()->deschedule(); 7613088Sgabeblack@google.com deschedule(ts); 7713072Sgabeblack@google.com } 7813076Sgabeblack@google.com timeSlots.clear(); 7913072Sgabeblack@google.com 8013072Sgabeblack@google.com // gem5 events. 8113072Sgabeblack@google.com if (readyEvent.scheduled()) 8213088Sgabeblack@google.com deschedule(&readyEvent); 8313072Sgabeblack@google.com if (pauseEvent.scheduled()) 8413088Sgabeblack@google.com deschedule(&pauseEvent); 8513072Sgabeblack@google.com if (stopEvent.scheduled()) 8613088Sgabeblack@google.com deschedule(&stopEvent); 8713072Sgabeblack@google.com if (starvationEvent.scheduled()) 8813088Sgabeblack@google.com deschedule(&starvationEvent); 8913072Sgabeblack@google.com if (maxTickEvent.scheduled()) 9013088Sgabeblack@google.com deschedule(&maxTickEvent); 9113245Sgabeblack@google.com if (timeAdvancesEvent.scheduled()) 9213245Sgabeblack@google.com deschedule(&timeAdvancesEvent); 9313072Sgabeblack@google.com 9413072Sgabeblack@google.com Process *p; 9513072Sgabeblack@google.com while ((p = initList.getNext())) 9613072Sgabeblack@google.com p->popListNode(); 9713176Sgabeblack@google.com while ((p = readyListMethods.getNext())) 9813176Sgabeblack@google.com p->popListNode(); 9913176Sgabeblack@google.com while ((p = readyListThreads.getNext())) 10013072Sgabeblack@google.com p->popListNode(); 10113072Sgabeblack@google.com 10213072Sgabeblack@google.com Channel *c; 10313072Sgabeblack@google.com while ((c = updateList.getNext())) 10413072Sgabeblack@google.com c->popListNode(); 10513072Sgabeblack@google.com} 10613072Sgabeblack@google.com 10712953Sgabeblack@google.comvoid 10813067Sgabeblack@google.comScheduler::initPhase() 10912953Sgabeblack@google.com{ 11013194Sgabeblack@google.com for (Process *p = initList.getNext(); p; p = initList.getNext()) { 11112957Sgabeblack@google.com p->popListNode(); 11213180Sgabeblack@google.com 11313194Sgabeblack@google.com if (p->dontInitialize()) { 11413194Sgabeblack@google.com if (!p->hasStaticSensitivities() && !p->internal()) { 11513194Sgabeblack@google.com SC_REPORT_WARNING( 11613194Sgabeblack@google.com "(W558) disable() or dont_initialize() called on " 11713194Sgabeblack@google.com "process with no static sensitivity, it will be " 11813194Sgabeblack@google.com "orphaned", p->name()); 11913194Sgabeblack@google.com } 12013194Sgabeblack@google.com } else { 12113194Sgabeblack@google.com p->ready(); 12213180Sgabeblack@google.com } 12312957Sgabeblack@google.com } 12412957Sgabeblack@google.com 12513186Sgabeblack@google.com runUpdate(); 12613186Sgabeblack@google.com runDelta(); 12713067Sgabeblack@google.com 12812985Sgabeblack@google.com for (auto ets: eventsToSchedule) 12912985Sgabeblack@google.com eq->schedule(ets.first, ets.second); 13012985Sgabeblack@google.com eventsToSchedule.clear(); 13112985Sgabeblack@google.com 13213068Sgabeblack@google.com if (_started) { 13313096Sgabeblack@google.com if (!runToTime && starved()) 13413068Sgabeblack@google.com scheduleStarvationEvent(); 13513069Sgabeblack@google.com kernel->status(::sc_core::SC_RUNNING); 13613068Sgabeblack@google.com } 13712961Sgabeblack@google.com 13813067Sgabeblack@google.com initDone = true; 13913186Sgabeblack@google.com 14013186Sgabeblack@google.com status(StatusOther); 14113245Sgabeblack@google.com 14213245Sgabeblack@google.com scheduleTimeAdvancesEvent(); 14312957Sgabeblack@google.com} 14412957Sgabeblack@google.com 14512957Sgabeblack@google.comvoid 14612957Sgabeblack@google.comScheduler::reg(Process *p) 14712957Sgabeblack@google.com{ 14813067Sgabeblack@google.com if (initDone) { 14913194Sgabeblack@google.com // If not marked as dontInitialize, mark as ready. 15013194Sgabeblack@google.com if (!p->dontInitialize()) 15113194Sgabeblack@google.com p->ready(); 15212957Sgabeblack@google.com } else { 15312957Sgabeblack@google.com // Otherwise, record that this process should be initialized once we 15412957Sgabeblack@google.com // get there. 15512957Sgabeblack@google.com initList.pushLast(p); 15612957Sgabeblack@google.com } 15712957Sgabeblack@google.com} 15812957Sgabeblack@google.com 15912957Sgabeblack@google.comvoid 16012953Sgabeblack@google.comScheduler::yield() 16112953Sgabeblack@google.com{ 16213176Sgabeblack@google.com // Pull a process from the active list. 16313209Sgabeblack@google.com _current = getNextReady(); 16412953Sgabeblack@google.com if (!_current) { 16512953Sgabeblack@google.com // There are no more processes, so return control to evaluate. 16612953Sgabeblack@google.com Fiber::primaryFiber()->run(); 16712953Sgabeblack@google.com } else { 16812953Sgabeblack@google.com _current->popListNode(); 16912953Sgabeblack@google.com // Switch to whatever Fiber is supposed to run this process. All 17012953Sgabeblack@google.com // Fibers which aren't running should be parked at this line. 17112953Sgabeblack@google.com _current->fiber()->run(); 17212961Sgabeblack@google.com // If the current process needs to be manually started, start it. 17313093Sgabeblack@google.com if (_current && _current->needsStart()) { 17413093Sgabeblack@google.com _current->needsStart(false); 17513308Sgabeblack@google.com // If a process hasn't started yet, "resetting" it just starts it 17613308Sgabeblack@google.com // and signals its reset event. 17713308Sgabeblack@google.com if (_current->inReset()) 17813308Sgabeblack@google.com _current->resetEvent().notify(); 17913182Sgabeblack@google.com try { 18013182Sgabeblack@google.com _current->run(); 18113182Sgabeblack@google.com } catch (...) { 18213182Sgabeblack@google.com throwToScMain(); 18313182Sgabeblack@google.com } 18413093Sgabeblack@google.com } 18512953Sgabeblack@google.com } 18613259Sgabeblack@google.com if (_current && !_current->needsStart()) { 18713259Sgabeblack@google.com if (_current->excWrapper) { 18813259Sgabeblack@google.com auto ew = _current->excWrapper; 18913259Sgabeblack@google.com _current->excWrapper = nullptr; 19013259Sgabeblack@google.com ew->throw_it(); 19113260Sgabeblack@google.com } else if (_current->inReset()) { 19213259Sgabeblack@google.com _current->reset(false); 19313259Sgabeblack@google.com } 19412995Sgabeblack@google.com } 19512953Sgabeblack@google.com} 19612953Sgabeblack@google.com 19712953Sgabeblack@google.comvoid 19812954Sgabeblack@google.comScheduler::ready(Process *p) 19912953Sgabeblack@google.com{ 20013154Sgabeblack@google.com if (_stopNow) 20113154Sgabeblack@google.com return; 20213154Sgabeblack@google.com 20313176Sgabeblack@google.com if (p->procKind() == ::sc_core::SC_METHOD_PROC_) 20413176Sgabeblack@google.com readyListMethods.pushLast(p); 20512954Sgabeblack@google.com else 20613176Sgabeblack@google.com readyListThreads.pushLast(p); 20712953Sgabeblack@google.com 20813244Sgabeblack@google.com if (!inEvaluate()) 20913244Sgabeblack@google.com scheduleReadyEvent(); 21012954Sgabeblack@google.com} 21112954Sgabeblack@google.com 21212954Sgabeblack@google.comvoid 21313133Sgabeblack@google.comScheduler::resume(Process *p) 21413133Sgabeblack@google.com{ 21513133Sgabeblack@google.com if (initDone) 21613133Sgabeblack@google.com ready(p); 21713133Sgabeblack@google.com else 21813133Sgabeblack@google.com initList.pushLast(p); 21913133Sgabeblack@google.com} 22013133Sgabeblack@google.com 22113133Sgabeblack@google.combool 22213176Sgabeblack@google.comlistContains(ListNode *list, ListNode *target) 22313176Sgabeblack@google.com{ 22413176Sgabeblack@google.com ListNode *n = list->nextListNode; 22513176Sgabeblack@google.com while (n != list) 22613176Sgabeblack@google.com if (n == target) 22713176Sgabeblack@google.com return true; 22813176Sgabeblack@google.com return false; 22913176Sgabeblack@google.com} 23013176Sgabeblack@google.com 23113176Sgabeblack@google.combool 23213133Sgabeblack@google.comScheduler::suspend(Process *p) 23313133Sgabeblack@google.com{ 23413176Sgabeblack@google.com bool was_ready; 23513133Sgabeblack@google.com if (initDone) { 23613194Sgabeblack@google.com // After initialization, check if we're on a ready list. 23713176Sgabeblack@google.com was_ready = (p->nextListNode != nullptr); 23813133Sgabeblack@google.com p->popListNode(); 23913133Sgabeblack@google.com } else { 24013194Sgabeblack@google.com // Nothing is ready before init. 24113194Sgabeblack@google.com was_ready = false; 24213133Sgabeblack@google.com } 24313176Sgabeblack@google.com return was_ready; 24413133Sgabeblack@google.com} 24513133Sgabeblack@google.com 24613133Sgabeblack@google.comvoid 24712954Sgabeblack@google.comScheduler::requestUpdate(Channel *c) 24812954Sgabeblack@google.com{ 24912954Sgabeblack@google.com updateList.pushLast(c); 25013244Sgabeblack@google.com if (!inEvaluate()) 25113244Sgabeblack@google.com scheduleReadyEvent(); 25212954Sgabeblack@google.com} 25312954Sgabeblack@google.com 25412954Sgabeblack@google.comvoid 25512954Sgabeblack@google.comScheduler::scheduleReadyEvent() 25612954Sgabeblack@google.com{ 25712954Sgabeblack@google.com // Schedule the evaluate and update phases. 25812954Sgabeblack@google.com if (!readyEvent.scheduled()) { 25913069Sgabeblack@google.com schedule(&readyEvent); 26012987Sgabeblack@google.com if (starvationEvent.scheduled()) 26113069Sgabeblack@google.com deschedule(&starvationEvent); 26212987Sgabeblack@google.com } 26312987Sgabeblack@google.com} 26412987Sgabeblack@google.com 26512987Sgabeblack@google.comvoid 26612987Sgabeblack@google.comScheduler::scheduleStarvationEvent() 26712987Sgabeblack@google.com{ 26812987Sgabeblack@google.com if (!starvationEvent.scheduled()) { 26913069Sgabeblack@google.com schedule(&starvationEvent); 27012987Sgabeblack@google.com if (readyEvent.scheduled()) 27113069Sgabeblack@google.com deschedule(&readyEvent); 27212954Sgabeblack@google.com } 27312954Sgabeblack@google.com} 27412954Sgabeblack@google.com 27512954Sgabeblack@google.comvoid 27612954Sgabeblack@google.comScheduler::runReady() 27712954Sgabeblack@google.com{ 27813245Sgabeblack@google.com scheduleTimeAdvancesEvent(); 27913245Sgabeblack@google.com 28013176Sgabeblack@google.com bool empty = readyListMethods.empty() && readyListThreads.empty(); 28113140Sgabeblack@google.com lastReadyTick = getCurTick(); 28212954Sgabeblack@google.com 28312954Sgabeblack@google.com // The evaluation phase. 28413245Sgabeblack@google.com status(StatusEvaluate); 28512953Sgabeblack@google.com do { 28613209Sgabeblack@google.com yield(); 28713209Sgabeblack@google.com } while (getNextReady()); 28813275Sgabeblack@google.com _current = nullptr; 28912954Sgabeblack@google.com 29013140Sgabeblack@google.com if (!empty) { 29112954Sgabeblack@google.com _numCycles++; 29213140Sgabeblack@google.com _changeStamp++; 29313140Sgabeblack@google.com } 29412954Sgabeblack@google.com 29513244Sgabeblack@google.com if (_stopNow) { 29613244Sgabeblack@google.com status(StatusOther); 29713154Sgabeblack@google.com return; 29813244Sgabeblack@google.com } 29913154Sgabeblack@google.com 30013186Sgabeblack@google.com runUpdate(); 30113245Sgabeblack@google.com if (!traceFiles.empty()) 30213245Sgabeblack@google.com trace(true); 30313186Sgabeblack@google.com runDelta(); 30413061Sgabeblack@google.com 30513096Sgabeblack@google.com if (!runToTime && starved()) 30613096Sgabeblack@google.com scheduleStarvationEvent(); 30713096Sgabeblack@google.com 30813064Sgabeblack@google.com if (runOnce) 30913064Sgabeblack@google.com schedulePause(); 31013186Sgabeblack@google.com 31113186Sgabeblack@google.com status(StatusOther); 31212953Sgabeblack@google.com} 31312953Sgabeblack@google.com 31412953Sgabeblack@google.comvoid 31513186Sgabeblack@google.comScheduler::runUpdate() 31612953Sgabeblack@google.com{ 31713186Sgabeblack@google.com status(StatusUpdate); 31813186Sgabeblack@google.com 31913188Sgabeblack@google.com try { 32013188Sgabeblack@google.com Channel *channel = updateList.getNext(); 32113188Sgabeblack@google.com while (channel) { 32213188Sgabeblack@google.com channel->popListNode(); 32313188Sgabeblack@google.com channel->update(); 32413188Sgabeblack@google.com channel = updateList.getNext(); 32513188Sgabeblack@google.com } 32613188Sgabeblack@google.com } catch (...) { 32713188Sgabeblack@google.com throwToScMain(); 32812954Sgabeblack@google.com } 32912953Sgabeblack@google.com} 33012953Sgabeblack@google.com 33112961Sgabeblack@google.comvoid 33213186Sgabeblack@google.comScheduler::runDelta() 33313186Sgabeblack@google.com{ 33413186Sgabeblack@google.com status(StatusDelta); 33513188Sgabeblack@google.com 33613188Sgabeblack@google.com try { 33713188Sgabeblack@google.com while (!deltas.empty()) 33813289Sgabeblack@google.com deltas.back()->run(); 33913188Sgabeblack@google.com } catch (...) { 34013188Sgabeblack@google.com throwToScMain(); 34113188Sgabeblack@google.com } 34213186Sgabeblack@google.com} 34313186Sgabeblack@google.com 34413186Sgabeblack@google.comvoid 34512961Sgabeblack@google.comScheduler::pause() 34612961Sgabeblack@google.com{ 34713186Sgabeblack@google.com status(StatusPaused); 34812982Sgabeblack@google.com kernel->status(::sc_core::SC_PAUSED); 34913061Sgabeblack@google.com runOnce = false; 35013182Sgabeblack@google.com if (scMain && !scMain->finished()) 35113182Sgabeblack@google.com scMain->run(); 35212961Sgabeblack@google.com} 35312961Sgabeblack@google.com 35412961Sgabeblack@google.comvoid 35512961Sgabeblack@google.comScheduler::stop() 35612961Sgabeblack@google.com{ 35713186Sgabeblack@google.com status(StatusStopped); 35812982Sgabeblack@google.com kernel->stop(); 35913074Sgabeblack@google.com 36013076Sgabeblack@google.com clear(); 36113074Sgabeblack@google.com 36213061Sgabeblack@google.com runOnce = false; 36313182Sgabeblack@google.com if (scMain && !scMain->finished()) 36413182Sgabeblack@google.com scMain->run(); 36512961Sgabeblack@google.com} 36612961Sgabeblack@google.com 36712961Sgabeblack@google.comvoid 36812961Sgabeblack@google.comScheduler::start(Tick max_tick, bool run_to_time) 36912961Sgabeblack@google.com{ 37012961Sgabeblack@google.com // We should be running from sc_main. Keep track of that Fiber to return 37112961Sgabeblack@google.com // to later. 37212961Sgabeblack@google.com scMain = Fiber::currentFiber(); 37312961Sgabeblack@google.com 37412961Sgabeblack@google.com _started = true; 37513186Sgabeblack@google.com status(StatusOther); 37612987Sgabeblack@google.com runToTime = run_to_time; 37712961Sgabeblack@google.com 37812961Sgabeblack@google.com maxTick = max_tick; 37913140Sgabeblack@google.com lastReadyTick = getCurTick(); 38012961Sgabeblack@google.com 38113067Sgabeblack@google.com if (initDone) { 38213096Sgabeblack@google.com if (!runToTime && starved()) 38313068Sgabeblack@google.com scheduleStarvationEvent(); 38412982Sgabeblack@google.com kernel->status(::sc_core::SC_RUNNING); 38512982Sgabeblack@google.com } 38612961Sgabeblack@google.com 38713069Sgabeblack@google.com schedule(&maxTickEvent, maxTick); 38813245Sgabeblack@google.com scheduleTimeAdvancesEvent(); 38913069Sgabeblack@google.com 39012961Sgabeblack@google.com // Return to gem5 to let it run events, etc. 39112961Sgabeblack@google.com Fiber::primaryFiber()->run(); 39212961Sgabeblack@google.com 39312961Sgabeblack@google.com if (pauseEvent.scheduled()) 39413088Sgabeblack@google.com deschedule(&pauseEvent); 39512961Sgabeblack@google.com if (stopEvent.scheduled()) 39613088Sgabeblack@google.com deschedule(&stopEvent); 39712961Sgabeblack@google.com if (maxTickEvent.scheduled()) 39813088Sgabeblack@google.com deschedule(&maxTickEvent); 39912987Sgabeblack@google.com if (starvationEvent.scheduled()) 40013088Sgabeblack@google.com deschedule(&starvationEvent); 40113182Sgabeblack@google.com 40213182Sgabeblack@google.com if (_throwToScMain) { 40313182Sgabeblack@google.com const ::sc_core::sc_report *to_throw = _throwToScMain; 40413182Sgabeblack@google.com _throwToScMain = nullptr; 40513182Sgabeblack@google.com throw *to_throw; 40613182Sgabeblack@google.com } 40712961Sgabeblack@google.com} 40812961Sgabeblack@google.com 40912961Sgabeblack@google.comvoid 41013061Sgabeblack@google.comScheduler::oneCycle() 41113061Sgabeblack@google.com{ 41213061Sgabeblack@google.com runOnce = true; 41313095Sgabeblack@google.com scheduleReadyEvent(); 41413061Sgabeblack@google.com start(::MaxTick, false); 41513061Sgabeblack@google.com} 41613061Sgabeblack@google.com 41713061Sgabeblack@google.comvoid 41812961Sgabeblack@google.comScheduler::schedulePause() 41912961Sgabeblack@google.com{ 42012961Sgabeblack@google.com if (pauseEvent.scheduled()) 42112961Sgabeblack@google.com return; 42212961Sgabeblack@google.com 42313088Sgabeblack@google.com schedule(&pauseEvent); 42412961Sgabeblack@google.com} 42512961Sgabeblack@google.com 42612961Sgabeblack@google.comvoid 42713264Sgabeblack@google.comScheduler::throwToScMain() 42813182Sgabeblack@google.com{ 42913264Sgabeblack@google.com ::sc_core::sc_report report = reportifyException(); 43013264Sgabeblack@google.com _throwToScMain = &report; 43113188Sgabeblack@google.com status(StatusOther); 43213182Sgabeblack@google.com scMain->run(); 43313182Sgabeblack@google.com} 43413182Sgabeblack@google.com 43513182Sgabeblack@google.comvoid 43612961Sgabeblack@google.comScheduler::scheduleStop(bool finish_delta) 43712961Sgabeblack@google.com{ 43812961Sgabeblack@google.com if (stopEvent.scheduled()) 43912961Sgabeblack@google.com return; 44012961Sgabeblack@google.com 44112961Sgabeblack@google.com if (!finish_delta) { 44213154Sgabeblack@google.com _stopNow = true; 44313076Sgabeblack@google.com // If we're not supposed to finish the delta cycle, flush all 44413076Sgabeblack@google.com // pending activity. 44513076Sgabeblack@google.com clear(); 44612961Sgabeblack@google.com } 44713088Sgabeblack@google.com schedule(&stopEvent); 44812961Sgabeblack@google.com} 44912961Sgabeblack@google.com 45013245Sgabeblack@google.comvoid 45113245Sgabeblack@google.comScheduler::trace(bool delta) 45213245Sgabeblack@google.com{ 45313245Sgabeblack@google.com for (auto tf: traceFiles) 45413245Sgabeblack@google.com tf->trace(delta); 45513245Sgabeblack@google.com} 45613245Sgabeblack@google.com 45712953Sgabeblack@google.comScheduler scheduler; 45812953Sgabeblack@google.com 45913182Sgabeblack@google.comnamespace { 46013182Sgabeblack@google.com 46113182Sgabeblack@google.comvoid 46213182Sgabeblack@google.comthrowingReportHandler(const ::sc_core::sc_report &r, 46313182Sgabeblack@google.com const ::sc_core::sc_actions &) 46413182Sgabeblack@google.com{ 46513182Sgabeblack@google.com throw r; 46613182Sgabeblack@google.com} 46713182Sgabeblack@google.com 46813182Sgabeblack@google.com} // anonymous namespace 46913182Sgabeblack@google.com 47013264Sgabeblack@google.comconst ::sc_core::sc_report 47113182Sgabeblack@google.comreportifyException() 47213182Sgabeblack@google.com{ 47313312Sgabeblack@google.com ::sc_core::sc_report_handler_proc old_handler = reportHandlerProc; 47413182Sgabeblack@google.com ::sc_core::sc_report_handler::set_handler(&throwingReportHandler); 47513182Sgabeblack@google.com 47613182Sgabeblack@google.com try { 47713182Sgabeblack@google.com try { 47813182Sgabeblack@google.com // Rethrow the current exception so we can catch it and throw an 47913182Sgabeblack@google.com // sc_report instead if it's not a type we recognize/can handle. 48013182Sgabeblack@google.com throw; 48113182Sgabeblack@google.com } catch (const ::sc_core::sc_report &) { 48213182Sgabeblack@google.com // It's already a sc_report, so nothing to do. 48313182Sgabeblack@google.com throw; 48413182Sgabeblack@google.com } catch (const ::sc_core::sc_unwind_exception &) { 48513182Sgabeblack@google.com panic("Kill/reset exception escaped a Process::run()"); 48613182Sgabeblack@google.com } catch (const std::exception &e) { 48713182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", e.what()); 48813182Sgabeblack@google.com } catch (const char *msg) { 48913182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", msg); 49013182Sgabeblack@google.com } catch (...) { 49113182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", "UNKNOWN EXCEPTION"); 49213182Sgabeblack@google.com } 49313182Sgabeblack@google.com } catch (const ::sc_core::sc_report &r) { 49413182Sgabeblack@google.com ::sc_core::sc_report_handler::set_handler(old_handler); 49513264Sgabeblack@google.com return r; 49613182Sgabeblack@google.com } 49713182Sgabeblack@google.com panic("No exception thrown in reportifyException."); 49813182Sgabeblack@google.com} 49913182Sgabeblack@google.com 50012953Sgabeblack@google.com} // namespace sc_gem5 501