scheduler.cc revision 13209
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" 3912953Sgabeblack@google.com 4012953Sgabeblack@google.comnamespace sc_gem5 4112953Sgabeblack@google.com{ 4212953Sgabeblack@google.com 4312954Sgabeblack@google.comScheduler::Scheduler() : 4412962Sgabeblack@google.com eq(nullptr), readyEvent(this, false, ReadyPriority), 4512961Sgabeblack@google.com pauseEvent(this, false, PausePriority), 4612961Sgabeblack@google.com stopEvent(this, false, StopPriority), 4713182Sgabeblack@google.com scMain(nullptr), _throwToScMain(nullptr), 4812987Sgabeblack@google.com starvationEvent(this, false, StarvationPriority), 4913203Sgabeblack@google.com _elaborationDone(false), _started(false), _stopNow(false), 5013203Sgabeblack@google.com _status(StatusOther), maxTickEvent(this, false, MaxTickPriority), 5113140Sgabeblack@google.com _numCycles(0), _changeStamp(0), _current(nullptr), initDone(false), 5213209Sgabeblack@google.com runOnce(false) 5312954Sgabeblack@google.com{} 5412953Sgabeblack@google.com 5513072Sgabeblack@google.comScheduler::~Scheduler() 5613072Sgabeblack@google.com{ 5713072Sgabeblack@google.com // Clear out everything that belongs to us to make sure nobody tries to 5813072Sgabeblack@google.com // clear themselves out after the scheduler goes away. 5913076Sgabeblack@google.com clear(); 6013076Sgabeblack@google.com} 6113072Sgabeblack@google.com 6213076Sgabeblack@google.comvoid 6313076Sgabeblack@google.comScheduler::clear() 6413076Sgabeblack@google.com{ 6513072Sgabeblack@google.com // Delta notifications. 6613144Sgabeblack@google.com while (!deltas.empty()) 6713144Sgabeblack@google.com deltas.front()->deschedule(); 6813072Sgabeblack@google.com 6913072Sgabeblack@google.com // Timed notifications. 7013076Sgabeblack@google.com for (auto &tsp: timeSlots) { 7113076Sgabeblack@google.com TimeSlot *&ts = tsp.second; 7213144Sgabeblack@google.com while (!ts->events.empty()) 7313144Sgabeblack@google.com ts->events.front()->deschedule(); 7413088Sgabeblack@google.com deschedule(ts); 7513072Sgabeblack@google.com } 7613076Sgabeblack@google.com timeSlots.clear(); 7713072Sgabeblack@google.com 7813072Sgabeblack@google.com // gem5 events. 7913072Sgabeblack@google.com if (readyEvent.scheduled()) 8013088Sgabeblack@google.com deschedule(&readyEvent); 8113072Sgabeblack@google.com if (pauseEvent.scheduled()) 8213088Sgabeblack@google.com deschedule(&pauseEvent); 8313072Sgabeblack@google.com if (stopEvent.scheduled()) 8413088Sgabeblack@google.com deschedule(&stopEvent); 8513072Sgabeblack@google.com if (starvationEvent.scheduled()) 8613088Sgabeblack@google.com deschedule(&starvationEvent); 8713072Sgabeblack@google.com if (maxTickEvent.scheduled()) 8813088Sgabeblack@google.com deschedule(&maxTickEvent); 8913072Sgabeblack@google.com 9013072Sgabeblack@google.com Process *p; 9113072Sgabeblack@google.com while ((p = initList.getNext())) 9213072Sgabeblack@google.com p->popListNode(); 9313176Sgabeblack@google.com while ((p = readyListMethods.getNext())) 9413176Sgabeblack@google.com p->popListNode(); 9513176Sgabeblack@google.com while ((p = readyListThreads.getNext())) 9613072Sgabeblack@google.com p->popListNode(); 9713072Sgabeblack@google.com 9813072Sgabeblack@google.com Channel *c; 9913072Sgabeblack@google.com while ((c = updateList.getNext())) 10013072Sgabeblack@google.com c->popListNode(); 10113072Sgabeblack@google.com} 10213072Sgabeblack@google.com 10312953Sgabeblack@google.comvoid 10413067Sgabeblack@google.comScheduler::initPhase() 10512953Sgabeblack@google.com{ 10613194Sgabeblack@google.com for (Process *p = initList.getNext(); p; p = initList.getNext()) { 10712957Sgabeblack@google.com p->popListNode(); 10813180Sgabeblack@google.com 10913194Sgabeblack@google.com if (p->dontInitialize()) { 11013194Sgabeblack@google.com if (!p->hasStaticSensitivities() && !p->internal()) { 11113194Sgabeblack@google.com SC_REPORT_WARNING( 11213194Sgabeblack@google.com "(W558) disable() or dont_initialize() called on " 11313194Sgabeblack@google.com "process with no static sensitivity, it will be " 11413194Sgabeblack@google.com "orphaned", p->name()); 11513194Sgabeblack@google.com } 11613194Sgabeblack@google.com } else { 11713194Sgabeblack@google.com p->ready(); 11813180Sgabeblack@google.com } 11912957Sgabeblack@google.com } 12012957Sgabeblack@google.com 12113186Sgabeblack@google.com runUpdate(); 12213186Sgabeblack@google.com runDelta(); 12313067Sgabeblack@google.com 12412985Sgabeblack@google.com for (auto ets: eventsToSchedule) 12512985Sgabeblack@google.com eq->schedule(ets.first, ets.second); 12612985Sgabeblack@google.com eventsToSchedule.clear(); 12712985Sgabeblack@google.com 12813068Sgabeblack@google.com if (_started) { 12913096Sgabeblack@google.com if (!runToTime && starved()) 13013068Sgabeblack@google.com scheduleStarvationEvent(); 13113069Sgabeblack@google.com kernel->status(::sc_core::SC_RUNNING); 13213068Sgabeblack@google.com } 13312961Sgabeblack@google.com 13413067Sgabeblack@google.com initDone = true; 13513186Sgabeblack@google.com 13613186Sgabeblack@google.com status(StatusOther); 13712957Sgabeblack@google.com} 13812957Sgabeblack@google.com 13912957Sgabeblack@google.comvoid 14012957Sgabeblack@google.comScheduler::reg(Process *p) 14112957Sgabeblack@google.com{ 14213067Sgabeblack@google.com if (initDone) { 14313194Sgabeblack@google.com // If not marked as dontInitialize, mark as ready. 14413194Sgabeblack@google.com if (!p->dontInitialize()) 14513194Sgabeblack@google.com p->ready(); 14612957Sgabeblack@google.com } else { 14712957Sgabeblack@google.com // Otherwise, record that this process should be initialized once we 14812957Sgabeblack@google.com // get there. 14912957Sgabeblack@google.com initList.pushLast(p); 15012957Sgabeblack@google.com } 15112957Sgabeblack@google.com} 15212957Sgabeblack@google.com 15312957Sgabeblack@google.comvoid 15412953Sgabeblack@google.comScheduler::yield() 15512953Sgabeblack@google.com{ 15613176Sgabeblack@google.com // Pull a process from the active list. 15713209Sgabeblack@google.com _current = getNextReady(); 15812953Sgabeblack@google.com if (!_current) { 15912953Sgabeblack@google.com // There are no more processes, so return control to evaluate. 16012953Sgabeblack@google.com Fiber::primaryFiber()->run(); 16112953Sgabeblack@google.com } else { 16212953Sgabeblack@google.com _current->popListNode(); 16312953Sgabeblack@google.com // Switch to whatever Fiber is supposed to run this process. All 16412953Sgabeblack@google.com // Fibers which aren't running should be parked at this line. 16512953Sgabeblack@google.com _current->fiber()->run(); 16612961Sgabeblack@google.com // If the current process needs to be manually started, start it. 16713093Sgabeblack@google.com if (_current && _current->needsStart()) { 16813093Sgabeblack@google.com _current->needsStart(false); 16913182Sgabeblack@google.com try { 17013182Sgabeblack@google.com _current->run(); 17113182Sgabeblack@google.com } catch (...) { 17213182Sgabeblack@google.com throwToScMain(); 17313182Sgabeblack@google.com } 17413093Sgabeblack@google.com } 17512953Sgabeblack@google.com } 17612995Sgabeblack@google.com if (_current && _current->excWrapper) { 17712995Sgabeblack@google.com // Make sure this isn't a method process. 17812995Sgabeblack@google.com assert(!_current->needsStart()); 17912995Sgabeblack@google.com auto ew = _current->excWrapper; 18012995Sgabeblack@google.com _current->excWrapper = nullptr; 18112995Sgabeblack@google.com ew->throw_it(); 18212995Sgabeblack@google.com } 18312953Sgabeblack@google.com} 18412953Sgabeblack@google.com 18512953Sgabeblack@google.comvoid 18612954Sgabeblack@google.comScheduler::ready(Process *p) 18712953Sgabeblack@google.com{ 18813154Sgabeblack@google.com if (_stopNow) 18913154Sgabeblack@google.com return; 19013154Sgabeblack@google.com 19113176Sgabeblack@google.com if (p->procKind() == ::sc_core::SC_METHOD_PROC_) 19213176Sgabeblack@google.com readyListMethods.pushLast(p); 19312954Sgabeblack@google.com else 19413176Sgabeblack@google.com readyListThreads.pushLast(p); 19512953Sgabeblack@google.com 19612954Sgabeblack@google.com scheduleReadyEvent(); 19712954Sgabeblack@google.com} 19812954Sgabeblack@google.com 19912954Sgabeblack@google.comvoid 20013133Sgabeblack@google.comScheduler::resume(Process *p) 20113133Sgabeblack@google.com{ 20213133Sgabeblack@google.com if (initDone) 20313133Sgabeblack@google.com ready(p); 20413133Sgabeblack@google.com else 20513133Sgabeblack@google.com initList.pushLast(p); 20613133Sgabeblack@google.com} 20713133Sgabeblack@google.com 20813133Sgabeblack@google.combool 20913176Sgabeblack@google.comlistContains(ListNode *list, ListNode *target) 21013176Sgabeblack@google.com{ 21113176Sgabeblack@google.com ListNode *n = list->nextListNode; 21213176Sgabeblack@google.com while (n != list) 21313176Sgabeblack@google.com if (n == target) 21413176Sgabeblack@google.com return true; 21513176Sgabeblack@google.com return false; 21613176Sgabeblack@google.com} 21713176Sgabeblack@google.com 21813176Sgabeblack@google.combool 21913133Sgabeblack@google.comScheduler::suspend(Process *p) 22013133Sgabeblack@google.com{ 22113176Sgabeblack@google.com bool was_ready; 22213133Sgabeblack@google.com if (initDone) { 22313194Sgabeblack@google.com // After initialization, check if we're on a ready list. 22413176Sgabeblack@google.com was_ready = (p->nextListNode != nullptr); 22513133Sgabeblack@google.com p->popListNode(); 22613133Sgabeblack@google.com } else { 22713194Sgabeblack@google.com // Nothing is ready before init. 22813194Sgabeblack@google.com was_ready = false; 22913133Sgabeblack@google.com } 23013176Sgabeblack@google.com return was_ready; 23113133Sgabeblack@google.com} 23213133Sgabeblack@google.com 23313133Sgabeblack@google.comvoid 23412954Sgabeblack@google.comScheduler::requestUpdate(Channel *c) 23512954Sgabeblack@google.com{ 23612954Sgabeblack@google.com updateList.pushLast(c); 23713069Sgabeblack@google.com scheduleReadyEvent(); 23812954Sgabeblack@google.com} 23912954Sgabeblack@google.com 24012954Sgabeblack@google.comvoid 24112954Sgabeblack@google.comScheduler::scheduleReadyEvent() 24212954Sgabeblack@google.com{ 24312954Sgabeblack@google.com // Schedule the evaluate and update phases. 24412954Sgabeblack@google.com if (!readyEvent.scheduled()) { 24513069Sgabeblack@google.com schedule(&readyEvent); 24612987Sgabeblack@google.com if (starvationEvent.scheduled()) 24713069Sgabeblack@google.com deschedule(&starvationEvent); 24812987Sgabeblack@google.com } 24912987Sgabeblack@google.com} 25012987Sgabeblack@google.com 25112987Sgabeblack@google.comvoid 25212987Sgabeblack@google.comScheduler::scheduleStarvationEvent() 25312987Sgabeblack@google.com{ 25412987Sgabeblack@google.com if (!starvationEvent.scheduled()) { 25513069Sgabeblack@google.com schedule(&starvationEvent); 25612987Sgabeblack@google.com if (readyEvent.scheduled()) 25713069Sgabeblack@google.com deschedule(&readyEvent); 25812954Sgabeblack@google.com } 25912954Sgabeblack@google.com} 26012954Sgabeblack@google.com 26112954Sgabeblack@google.comvoid 26212954Sgabeblack@google.comScheduler::runReady() 26312954Sgabeblack@google.com{ 26413176Sgabeblack@google.com bool empty = readyListMethods.empty() && readyListThreads.empty(); 26513140Sgabeblack@google.com lastReadyTick = getCurTick(); 26612954Sgabeblack@google.com 26712954Sgabeblack@google.com // The evaluation phase. 26812953Sgabeblack@google.com do { 26913209Sgabeblack@google.com yield(); 27013209Sgabeblack@google.com } while (getNextReady()); 27112954Sgabeblack@google.com 27213140Sgabeblack@google.com if (!empty) { 27312954Sgabeblack@google.com _numCycles++; 27413140Sgabeblack@google.com _changeStamp++; 27513140Sgabeblack@google.com } 27612954Sgabeblack@google.com 27713154Sgabeblack@google.com if (_stopNow) 27813154Sgabeblack@google.com return; 27913154Sgabeblack@google.com 28013186Sgabeblack@google.com runUpdate(); 28113186Sgabeblack@google.com runDelta(); 28213061Sgabeblack@google.com 28313096Sgabeblack@google.com if (!runToTime && starved()) 28413096Sgabeblack@google.com scheduleStarvationEvent(); 28513096Sgabeblack@google.com 28613064Sgabeblack@google.com if (runOnce) 28713064Sgabeblack@google.com schedulePause(); 28813186Sgabeblack@google.com 28913186Sgabeblack@google.com status(StatusOther); 29012953Sgabeblack@google.com} 29112953Sgabeblack@google.com 29212953Sgabeblack@google.comvoid 29313186Sgabeblack@google.comScheduler::runUpdate() 29412953Sgabeblack@google.com{ 29513186Sgabeblack@google.com status(StatusUpdate); 29613186Sgabeblack@google.com 29713188Sgabeblack@google.com try { 29813188Sgabeblack@google.com Channel *channel = updateList.getNext(); 29913188Sgabeblack@google.com while (channel) { 30013188Sgabeblack@google.com channel->popListNode(); 30113188Sgabeblack@google.com channel->update(); 30213188Sgabeblack@google.com channel = updateList.getNext(); 30313188Sgabeblack@google.com } 30413188Sgabeblack@google.com } catch (...) { 30513188Sgabeblack@google.com throwToScMain(); 30612954Sgabeblack@google.com } 30712953Sgabeblack@google.com} 30812953Sgabeblack@google.com 30912961Sgabeblack@google.comvoid 31013186Sgabeblack@google.comScheduler::runDelta() 31113186Sgabeblack@google.com{ 31213186Sgabeblack@google.com status(StatusDelta); 31313188Sgabeblack@google.com 31413188Sgabeblack@google.com try { 31513188Sgabeblack@google.com while (!deltas.empty()) 31613188Sgabeblack@google.com deltas.front()->run(); 31713188Sgabeblack@google.com } catch (...) { 31813188Sgabeblack@google.com throwToScMain(); 31913188Sgabeblack@google.com } 32013186Sgabeblack@google.com} 32113186Sgabeblack@google.com 32213186Sgabeblack@google.comvoid 32312961Sgabeblack@google.comScheduler::pause() 32412961Sgabeblack@google.com{ 32513186Sgabeblack@google.com status(StatusPaused); 32612982Sgabeblack@google.com kernel->status(::sc_core::SC_PAUSED); 32713061Sgabeblack@google.com runOnce = false; 32813182Sgabeblack@google.com if (scMain && !scMain->finished()) 32913182Sgabeblack@google.com scMain->run(); 33012961Sgabeblack@google.com} 33112961Sgabeblack@google.com 33212961Sgabeblack@google.comvoid 33312961Sgabeblack@google.comScheduler::stop() 33412961Sgabeblack@google.com{ 33513186Sgabeblack@google.com status(StatusStopped); 33612982Sgabeblack@google.com kernel->stop(); 33713074Sgabeblack@google.com 33813076Sgabeblack@google.com clear(); 33913074Sgabeblack@google.com 34013061Sgabeblack@google.com runOnce = false; 34113182Sgabeblack@google.com if (scMain && !scMain->finished()) 34213182Sgabeblack@google.com scMain->run(); 34312961Sgabeblack@google.com} 34412961Sgabeblack@google.com 34512961Sgabeblack@google.comvoid 34612961Sgabeblack@google.comScheduler::start(Tick max_tick, bool run_to_time) 34712961Sgabeblack@google.com{ 34812961Sgabeblack@google.com // We should be running from sc_main. Keep track of that Fiber to return 34912961Sgabeblack@google.com // to later. 35012961Sgabeblack@google.com scMain = Fiber::currentFiber(); 35112961Sgabeblack@google.com 35212961Sgabeblack@google.com _started = true; 35313186Sgabeblack@google.com status(StatusOther); 35412987Sgabeblack@google.com runToTime = run_to_time; 35512961Sgabeblack@google.com 35612961Sgabeblack@google.com maxTick = max_tick; 35713140Sgabeblack@google.com lastReadyTick = getCurTick(); 35812961Sgabeblack@google.com 35913067Sgabeblack@google.com if (initDone) { 36013096Sgabeblack@google.com if (!runToTime && starved()) 36113068Sgabeblack@google.com scheduleStarvationEvent(); 36212982Sgabeblack@google.com kernel->status(::sc_core::SC_RUNNING); 36312982Sgabeblack@google.com } 36412961Sgabeblack@google.com 36513069Sgabeblack@google.com schedule(&maxTickEvent, maxTick); 36613069Sgabeblack@google.com 36712961Sgabeblack@google.com // Return to gem5 to let it run events, etc. 36812961Sgabeblack@google.com Fiber::primaryFiber()->run(); 36912961Sgabeblack@google.com 37012961Sgabeblack@google.com if (pauseEvent.scheduled()) 37113088Sgabeblack@google.com deschedule(&pauseEvent); 37212961Sgabeblack@google.com if (stopEvent.scheduled()) 37313088Sgabeblack@google.com deschedule(&stopEvent); 37412961Sgabeblack@google.com if (maxTickEvent.scheduled()) 37513088Sgabeblack@google.com deschedule(&maxTickEvent); 37612987Sgabeblack@google.com if (starvationEvent.scheduled()) 37713088Sgabeblack@google.com deschedule(&starvationEvent); 37813182Sgabeblack@google.com 37913182Sgabeblack@google.com if (_throwToScMain) { 38013182Sgabeblack@google.com const ::sc_core::sc_report *to_throw = _throwToScMain; 38113182Sgabeblack@google.com _throwToScMain = nullptr; 38213182Sgabeblack@google.com throw *to_throw; 38313182Sgabeblack@google.com } 38412961Sgabeblack@google.com} 38512961Sgabeblack@google.com 38612961Sgabeblack@google.comvoid 38713061Sgabeblack@google.comScheduler::oneCycle() 38813061Sgabeblack@google.com{ 38913061Sgabeblack@google.com runOnce = true; 39013095Sgabeblack@google.com scheduleReadyEvent(); 39113061Sgabeblack@google.com start(::MaxTick, false); 39213061Sgabeblack@google.com} 39313061Sgabeblack@google.com 39413061Sgabeblack@google.comvoid 39512961Sgabeblack@google.comScheduler::schedulePause() 39612961Sgabeblack@google.com{ 39712961Sgabeblack@google.com if (pauseEvent.scheduled()) 39812961Sgabeblack@google.com return; 39912961Sgabeblack@google.com 40013088Sgabeblack@google.com schedule(&pauseEvent); 40112961Sgabeblack@google.com} 40212961Sgabeblack@google.com 40312961Sgabeblack@google.comvoid 40413182Sgabeblack@google.comScheduler::throwToScMain(const ::sc_core::sc_report *r) 40513182Sgabeblack@google.com{ 40613182Sgabeblack@google.com if (!r) 40713182Sgabeblack@google.com r = reportifyException(); 40813182Sgabeblack@google.com _throwToScMain = r; 40913188Sgabeblack@google.com status(StatusOther); 41013182Sgabeblack@google.com scMain->run(); 41113182Sgabeblack@google.com} 41213182Sgabeblack@google.com 41313182Sgabeblack@google.comvoid 41412961Sgabeblack@google.comScheduler::scheduleStop(bool finish_delta) 41512961Sgabeblack@google.com{ 41612961Sgabeblack@google.com if (stopEvent.scheduled()) 41712961Sgabeblack@google.com return; 41812961Sgabeblack@google.com 41912961Sgabeblack@google.com if (!finish_delta) { 42013154Sgabeblack@google.com _stopNow = true; 42113076Sgabeblack@google.com // If we're not supposed to finish the delta cycle, flush all 42213076Sgabeblack@google.com // pending activity. 42313076Sgabeblack@google.com clear(); 42412961Sgabeblack@google.com } 42513088Sgabeblack@google.com schedule(&stopEvent); 42612961Sgabeblack@google.com} 42712961Sgabeblack@google.com 42812953Sgabeblack@google.comScheduler scheduler; 42912953Sgabeblack@google.com 43013182Sgabeblack@google.comnamespace { 43113182Sgabeblack@google.com 43213182Sgabeblack@google.comvoid 43313182Sgabeblack@google.comthrowingReportHandler(const ::sc_core::sc_report &r, 43413182Sgabeblack@google.com const ::sc_core::sc_actions &) 43513182Sgabeblack@google.com{ 43613182Sgabeblack@google.com throw r; 43713182Sgabeblack@google.com} 43813182Sgabeblack@google.com 43913182Sgabeblack@google.com} // anonymous namespace 44013182Sgabeblack@google.com 44113182Sgabeblack@google.comconst ::sc_core::sc_report * 44213182Sgabeblack@google.comreportifyException() 44313182Sgabeblack@google.com{ 44413182Sgabeblack@google.com ::sc_core::sc_report_handler_proc old_handler = 44513182Sgabeblack@google.com ::sc_core::sc_report_handler::get_handler(); 44613182Sgabeblack@google.com ::sc_core::sc_report_handler::set_handler(&throwingReportHandler); 44713182Sgabeblack@google.com 44813182Sgabeblack@google.com try { 44913182Sgabeblack@google.com try { 45013182Sgabeblack@google.com // Rethrow the current exception so we can catch it and throw an 45113182Sgabeblack@google.com // sc_report instead if it's not a type we recognize/can handle. 45213182Sgabeblack@google.com throw; 45313182Sgabeblack@google.com } catch (const ::sc_core::sc_report &) { 45413182Sgabeblack@google.com // It's already a sc_report, so nothing to do. 45513182Sgabeblack@google.com throw; 45613182Sgabeblack@google.com } catch (const ::sc_core::sc_unwind_exception &) { 45713182Sgabeblack@google.com panic("Kill/reset exception escaped a Process::run()"); 45813182Sgabeblack@google.com } catch (const std::exception &e) { 45913182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", e.what()); 46013182Sgabeblack@google.com } catch (const char *msg) { 46113182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", msg); 46213182Sgabeblack@google.com } catch (...) { 46313182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", "UNKNOWN EXCEPTION"); 46413182Sgabeblack@google.com } 46513182Sgabeblack@google.com } catch (const ::sc_core::sc_report &r) { 46613182Sgabeblack@google.com ::sc_core::sc_report_handler::set_handler(old_handler); 46713182Sgabeblack@google.com return &r; 46813182Sgabeblack@google.com } 46913182Sgabeblack@google.com panic("No exception thrown in reportifyException."); 47013182Sgabeblack@google.com} 47113182Sgabeblack@google.com 47212953Sgabeblack@google.com} // namespace sc_gem5 473