scheduler.cc revision 13188
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), 4913186Sgabeblack@google.com _started(false), _stopNow(false), _status(StatusOther), 5012961Sgabeblack@google.com maxTickEvent(this, false, MaxTickPriority), 5113140Sgabeblack@google.com _numCycles(0), _changeStamp(0), _current(nullptr), initDone(false), 5213176Sgabeblack@google.com runOnce(false), readyList(nullptr) 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 = toFinalize.getNext())) 9213072Sgabeblack@google.com p->popListNode(); 9313072Sgabeblack@google.com while ((p = initList.getNext())) 9413072Sgabeblack@google.com p->popListNode(); 9513176Sgabeblack@google.com while ((p = readyListMethods.getNext())) 9613176Sgabeblack@google.com p->popListNode(); 9713176Sgabeblack@google.com while ((p = readyListThreads.getNext())) 9813072Sgabeblack@google.com p->popListNode(); 9913072Sgabeblack@google.com 10013072Sgabeblack@google.com Channel *c; 10113072Sgabeblack@google.com while ((c = updateList.getNext())) 10213072Sgabeblack@google.com c->popListNode(); 10313072Sgabeblack@google.com} 10413072Sgabeblack@google.com 10512953Sgabeblack@google.comvoid 10613067Sgabeblack@google.comScheduler::initPhase() 10712953Sgabeblack@google.com{ 10812957Sgabeblack@google.com for (Process *p = toFinalize.getNext(); p; p = toFinalize.getNext()) { 10912957Sgabeblack@google.com p->finalize(); 11012957Sgabeblack@google.com p->popListNode(); 11113180Sgabeblack@google.com 11213180Sgabeblack@google.com if (!p->hasStaticSensitivities() && !p->internal()) { 11313180Sgabeblack@google.com SC_REPORT_WARNING( 11413180Sgabeblack@google.com "(W558) disable() or dont_initialize() called on process " 11513180Sgabeblack@google.com "with no static sensitivity, it will be orphaned", 11613180Sgabeblack@google.com p->name()); 11713180Sgabeblack@google.com } 11812957Sgabeblack@google.com } 11912957Sgabeblack@google.com 12012957Sgabeblack@google.com for (Process *p = initList.getNext(); p; p = initList.getNext()) { 12112957Sgabeblack@google.com p->finalize(); 12212996Sgabeblack@google.com p->popListNode(); 12312959Sgabeblack@google.com p->ready(); 12412957Sgabeblack@google.com } 12512957Sgabeblack@google.com 12613186Sgabeblack@google.com runUpdate(); 12713186Sgabeblack@google.com runDelta(); 12813067Sgabeblack@google.com 12912985Sgabeblack@google.com for (auto ets: eventsToSchedule) 13012985Sgabeblack@google.com eq->schedule(ets.first, ets.second); 13112985Sgabeblack@google.com eventsToSchedule.clear(); 13212985Sgabeblack@google.com 13313068Sgabeblack@google.com if (_started) { 13413096Sgabeblack@google.com if (!runToTime && starved()) 13513068Sgabeblack@google.com scheduleStarvationEvent(); 13613069Sgabeblack@google.com kernel->status(::sc_core::SC_RUNNING); 13713068Sgabeblack@google.com } 13812961Sgabeblack@google.com 13913067Sgabeblack@google.com initDone = true; 14013186Sgabeblack@google.com 14113186Sgabeblack@google.com status(StatusOther); 14212957Sgabeblack@google.com} 14312957Sgabeblack@google.com 14412957Sgabeblack@google.comvoid 14512957Sgabeblack@google.comScheduler::reg(Process *p) 14612957Sgabeblack@google.com{ 14713067Sgabeblack@google.com if (initDone) { 14812957Sgabeblack@google.com // If we're past initialization, finalize static sensitivity. 14912957Sgabeblack@google.com p->finalize(); 15012957Sgabeblack@google.com // Mark the process as ready. 15112959Sgabeblack@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 16012957Sgabeblack@google.comScheduler::dontInitialize(Process *p) 16112957Sgabeblack@google.com{ 16213067Sgabeblack@google.com if (initDone) { 16312957Sgabeblack@google.com // Pop this process off of the ready list. 16412957Sgabeblack@google.com p->popListNode(); 16512957Sgabeblack@google.com } else { 16612957Sgabeblack@google.com // Push this process onto the list of processes which still need 16712957Sgabeblack@google.com // their static sensitivity to be finalized. That implicitly pops it 16812957Sgabeblack@google.com // off the list of processes to be initialized/marked ready. 16912957Sgabeblack@google.com toFinalize.pushLast(p); 17012957Sgabeblack@google.com } 17112953Sgabeblack@google.com} 17212953Sgabeblack@google.com 17312953Sgabeblack@google.comvoid 17412953Sgabeblack@google.comScheduler::yield() 17512953Sgabeblack@google.com{ 17613176Sgabeblack@google.com // Pull a process from the active list. 17713176Sgabeblack@google.com _current = readyList->getNext(); 17812953Sgabeblack@google.com if (!_current) { 17912953Sgabeblack@google.com // There are no more processes, so return control to evaluate. 18012953Sgabeblack@google.com Fiber::primaryFiber()->run(); 18112953Sgabeblack@google.com } else { 18212953Sgabeblack@google.com _current->popListNode(); 18312953Sgabeblack@google.com // Switch to whatever Fiber is supposed to run this process. All 18412953Sgabeblack@google.com // Fibers which aren't running should be parked at this line. 18512953Sgabeblack@google.com _current->fiber()->run(); 18612961Sgabeblack@google.com // If the current process needs to be manually started, start it. 18713093Sgabeblack@google.com if (_current && _current->needsStart()) { 18813093Sgabeblack@google.com _current->needsStart(false); 18913182Sgabeblack@google.com try { 19013182Sgabeblack@google.com _current->run(); 19113182Sgabeblack@google.com } catch (...) { 19213182Sgabeblack@google.com throwToScMain(); 19313182Sgabeblack@google.com } 19413093Sgabeblack@google.com } 19512953Sgabeblack@google.com } 19612995Sgabeblack@google.com if (_current && _current->excWrapper) { 19712995Sgabeblack@google.com // Make sure this isn't a method process. 19812995Sgabeblack@google.com assert(!_current->needsStart()); 19912995Sgabeblack@google.com auto ew = _current->excWrapper; 20012995Sgabeblack@google.com _current->excWrapper = nullptr; 20112995Sgabeblack@google.com ew->throw_it(); 20212995Sgabeblack@google.com } 20312953Sgabeblack@google.com} 20412953Sgabeblack@google.com 20512953Sgabeblack@google.comvoid 20612954Sgabeblack@google.comScheduler::ready(Process *p) 20712953Sgabeblack@google.com{ 20813154Sgabeblack@google.com if (_stopNow) 20913154Sgabeblack@google.com return; 21013154Sgabeblack@google.com 21113176Sgabeblack@google.com if (p->procKind() == ::sc_core::SC_METHOD_PROC_) 21213176Sgabeblack@google.com readyListMethods.pushLast(p); 21312954Sgabeblack@google.com else 21413176Sgabeblack@google.com readyListThreads.pushLast(p); 21512953Sgabeblack@google.com 21612954Sgabeblack@google.com scheduleReadyEvent(); 21712954Sgabeblack@google.com} 21812954Sgabeblack@google.com 21912954Sgabeblack@google.comvoid 22013133Sgabeblack@google.comScheduler::resume(Process *p) 22113133Sgabeblack@google.com{ 22213133Sgabeblack@google.com if (initDone) 22313133Sgabeblack@google.com ready(p); 22413133Sgabeblack@google.com else 22513133Sgabeblack@google.com initList.pushLast(p); 22613133Sgabeblack@google.com} 22713133Sgabeblack@google.com 22813133Sgabeblack@google.combool 22913176Sgabeblack@google.comlistContains(ListNode *list, ListNode *target) 23013176Sgabeblack@google.com{ 23113176Sgabeblack@google.com ListNode *n = list->nextListNode; 23213176Sgabeblack@google.com while (n != list) 23313176Sgabeblack@google.com if (n == target) 23413176Sgabeblack@google.com return true; 23513176Sgabeblack@google.com return false; 23613176Sgabeblack@google.com} 23713176Sgabeblack@google.com 23813176Sgabeblack@google.combool 23913133Sgabeblack@google.comScheduler::suspend(Process *p) 24013133Sgabeblack@google.com{ 24113176Sgabeblack@google.com bool was_ready; 24213133Sgabeblack@google.com if (initDone) { 24313133Sgabeblack@google.com // After initialization, the only list we can be on is the ready list. 24413176Sgabeblack@google.com was_ready = (p->nextListNode != nullptr); 24513133Sgabeblack@google.com p->popListNode(); 24613133Sgabeblack@google.com } else { 24713176Sgabeblack@google.com // Check the ready lists to see if we find this process. 24813176Sgabeblack@google.com was_ready = listContains(&readyListMethods, p) || 24913176Sgabeblack@google.com listContains(&readyListThreads, p); 25013133Sgabeblack@google.com if (was_ready) 25113133Sgabeblack@google.com toFinalize.pushLast(p); 25213133Sgabeblack@google.com } 25313176Sgabeblack@google.com return was_ready; 25413133Sgabeblack@google.com} 25513133Sgabeblack@google.com 25613133Sgabeblack@google.comvoid 25712954Sgabeblack@google.comScheduler::requestUpdate(Channel *c) 25812954Sgabeblack@google.com{ 25912954Sgabeblack@google.com updateList.pushLast(c); 26013069Sgabeblack@google.com scheduleReadyEvent(); 26112954Sgabeblack@google.com} 26212954Sgabeblack@google.com 26312954Sgabeblack@google.comvoid 26412954Sgabeblack@google.comScheduler::scheduleReadyEvent() 26512954Sgabeblack@google.com{ 26612954Sgabeblack@google.com // Schedule the evaluate and update phases. 26712954Sgabeblack@google.com if (!readyEvent.scheduled()) { 26813069Sgabeblack@google.com schedule(&readyEvent); 26912987Sgabeblack@google.com if (starvationEvent.scheduled()) 27013069Sgabeblack@google.com deschedule(&starvationEvent); 27112987Sgabeblack@google.com } 27212987Sgabeblack@google.com} 27312987Sgabeblack@google.com 27412987Sgabeblack@google.comvoid 27512987Sgabeblack@google.comScheduler::scheduleStarvationEvent() 27612987Sgabeblack@google.com{ 27712987Sgabeblack@google.com if (!starvationEvent.scheduled()) { 27813069Sgabeblack@google.com schedule(&starvationEvent); 27912987Sgabeblack@google.com if (readyEvent.scheduled()) 28013069Sgabeblack@google.com deschedule(&readyEvent); 28112954Sgabeblack@google.com } 28212954Sgabeblack@google.com} 28312954Sgabeblack@google.com 28412954Sgabeblack@google.comvoid 28512954Sgabeblack@google.comScheduler::runReady() 28612954Sgabeblack@google.com{ 28713176Sgabeblack@google.com bool empty = readyListMethods.empty() && readyListThreads.empty(); 28813140Sgabeblack@google.com lastReadyTick = getCurTick(); 28912954Sgabeblack@google.com 29012954Sgabeblack@google.com // The evaluation phase. 29112953Sgabeblack@google.com do { 29213176Sgabeblack@google.com // We run methods and threads in two seperate passes to emulate how 29313176Sgabeblack@google.com // Accellera orders things, but without having to scan through a 29413176Sgabeblack@google.com // unified list to find the next process of the correct type. 29513176Sgabeblack@google.com readyList = &readyListMethods; 29613176Sgabeblack@google.com while (!readyListMethods.empty()) 29713176Sgabeblack@google.com yield(); 29813176Sgabeblack@google.com 29913176Sgabeblack@google.com readyList = &readyListThreads; 30013176Sgabeblack@google.com while (!readyListThreads.empty()) 30113176Sgabeblack@google.com yield(); 30213176Sgabeblack@google.com 30313176Sgabeblack@google.com // We already know that readyListThreads is empty at this point. 30413176Sgabeblack@google.com } while (!readyListMethods.empty()); 30512954Sgabeblack@google.com 30613140Sgabeblack@google.com if (!empty) { 30712954Sgabeblack@google.com _numCycles++; 30813140Sgabeblack@google.com _changeStamp++; 30913140Sgabeblack@google.com } 31012954Sgabeblack@google.com 31113154Sgabeblack@google.com if (_stopNow) 31213154Sgabeblack@google.com return; 31313154Sgabeblack@google.com 31413186Sgabeblack@google.com runUpdate(); 31513186Sgabeblack@google.com runDelta(); 31613061Sgabeblack@google.com 31713096Sgabeblack@google.com if (!runToTime && starved()) 31813096Sgabeblack@google.com scheduleStarvationEvent(); 31913096Sgabeblack@google.com 32013064Sgabeblack@google.com if (runOnce) 32113064Sgabeblack@google.com schedulePause(); 32213186Sgabeblack@google.com 32313186Sgabeblack@google.com status(StatusOther); 32412953Sgabeblack@google.com} 32512953Sgabeblack@google.com 32612953Sgabeblack@google.comvoid 32713186Sgabeblack@google.comScheduler::runUpdate() 32812953Sgabeblack@google.com{ 32913186Sgabeblack@google.com status(StatusUpdate); 33013186Sgabeblack@google.com 33113188Sgabeblack@google.com try { 33213188Sgabeblack@google.com Channel *channel = updateList.getNext(); 33313188Sgabeblack@google.com while (channel) { 33413188Sgabeblack@google.com channel->popListNode(); 33513188Sgabeblack@google.com channel->update(); 33613188Sgabeblack@google.com channel = updateList.getNext(); 33713188Sgabeblack@google.com } 33813188Sgabeblack@google.com } catch (...) { 33913188Sgabeblack@google.com throwToScMain(); 34012954Sgabeblack@google.com } 34112953Sgabeblack@google.com} 34212953Sgabeblack@google.com 34312961Sgabeblack@google.comvoid 34413186Sgabeblack@google.comScheduler::runDelta() 34513186Sgabeblack@google.com{ 34613186Sgabeblack@google.com status(StatusDelta); 34713188Sgabeblack@google.com 34813188Sgabeblack@google.com try { 34913188Sgabeblack@google.com while (!deltas.empty()) 35013188Sgabeblack@google.com deltas.front()->run(); 35113188Sgabeblack@google.com } catch (...) { 35213188Sgabeblack@google.com throwToScMain(); 35313188Sgabeblack@google.com } 35413186Sgabeblack@google.com} 35513186Sgabeblack@google.com 35613186Sgabeblack@google.comvoid 35712961Sgabeblack@google.comScheduler::pause() 35812961Sgabeblack@google.com{ 35913186Sgabeblack@google.com status(StatusPaused); 36012982Sgabeblack@google.com kernel->status(::sc_core::SC_PAUSED); 36113061Sgabeblack@google.com runOnce = false; 36213182Sgabeblack@google.com if (scMain && !scMain->finished()) 36313182Sgabeblack@google.com scMain->run(); 36412961Sgabeblack@google.com} 36512961Sgabeblack@google.com 36612961Sgabeblack@google.comvoid 36712961Sgabeblack@google.comScheduler::stop() 36812961Sgabeblack@google.com{ 36913186Sgabeblack@google.com status(StatusStopped); 37012982Sgabeblack@google.com kernel->stop(); 37113074Sgabeblack@google.com 37213076Sgabeblack@google.com clear(); 37313074Sgabeblack@google.com 37413061Sgabeblack@google.com runOnce = false; 37513182Sgabeblack@google.com if (scMain && !scMain->finished()) 37613182Sgabeblack@google.com scMain->run(); 37712961Sgabeblack@google.com} 37812961Sgabeblack@google.com 37912961Sgabeblack@google.comvoid 38012961Sgabeblack@google.comScheduler::start(Tick max_tick, bool run_to_time) 38112961Sgabeblack@google.com{ 38212961Sgabeblack@google.com // We should be running from sc_main. Keep track of that Fiber to return 38312961Sgabeblack@google.com // to later. 38412961Sgabeblack@google.com scMain = Fiber::currentFiber(); 38512961Sgabeblack@google.com 38612961Sgabeblack@google.com _started = true; 38713186Sgabeblack@google.com status(StatusOther); 38812987Sgabeblack@google.com runToTime = run_to_time; 38912961Sgabeblack@google.com 39012961Sgabeblack@google.com maxTick = max_tick; 39113140Sgabeblack@google.com lastReadyTick = getCurTick(); 39212961Sgabeblack@google.com 39313067Sgabeblack@google.com if (initDone) { 39413096Sgabeblack@google.com if (!runToTime && starved()) 39513068Sgabeblack@google.com scheduleStarvationEvent(); 39612982Sgabeblack@google.com kernel->status(::sc_core::SC_RUNNING); 39712982Sgabeblack@google.com } 39812961Sgabeblack@google.com 39913069Sgabeblack@google.com schedule(&maxTickEvent, maxTick); 40013069Sgabeblack@google.com 40112961Sgabeblack@google.com // Return to gem5 to let it run events, etc. 40212961Sgabeblack@google.com Fiber::primaryFiber()->run(); 40312961Sgabeblack@google.com 40412961Sgabeblack@google.com if (pauseEvent.scheduled()) 40513088Sgabeblack@google.com deschedule(&pauseEvent); 40612961Sgabeblack@google.com if (stopEvent.scheduled()) 40713088Sgabeblack@google.com deschedule(&stopEvent); 40812961Sgabeblack@google.com if (maxTickEvent.scheduled()) 40913088Sgabeblack@google.com deschedule(&maxTickEvent); 41012987Sgabeblack@google.com if (starvationEvent.scheduled()) 41113088Sgabeblack@google.com deschedule(&starvationEvent); 41213182Sgabeblack@google.com 41313182Sgabeblack@google.com if (_throwToScMain) { 41413182Sgabeblack@google.com const ::sc_core::sc_report *to_throw = _throwToScMain; 41513182Sgabeblack@google.com _throwToScMain = nullptr; 41613182Sgabeblack@google.com throw *to_throw; 41713182Sgabeblack@google.com } 41812961Sgabeblack@google.com} 41912961Sgabeblack@google.com 42012961Sgabeblack@google.comvoid 42113061Sgabeblack@google.comScheduler::oneCycle() 42213061Sgabeblack@google.com{ 42313061Sgabeblack@google.com runOnce = true; 42413095Sgabeblack@google.com scheduleReadyEvent(); 42513061Sgabeblack@google.com start(::MaxTick, false); 42613061Sgabeblack@google.com} 42713061Sgabeblack@google.com 42813061Sgabeblack@google.comvoid 42912961Sgabeblack@google.comScheduler::schedulePause() 43012961Sgabeblack@google.com{ 43112961Sgabeblack@google.com if (pauseEvent.scheduled()) 43212961Sgabeblack@google.com return; 43312961Sgabeblack@google.com 43413088Sgabeblack@google.com schedule(&pauseEvent); 43512961Sgabeblack@google.com} 43612961Sgabeblack@google.com 43712961Sgabeblack@google.comvoid 43813182Sgabeblack@google.comScheduler::throwToScMain(const ::sc_core::sc_report *r) 43913182Sgabeblack@google.com{ 44013182Sgabeblack@google.com if (!r) 44113182Sgabeblack@google.com r = reportifyException(); 44213182Sgabeblack@google.com _throwToScMain = r; 44313188Sgabeblack@google.com status(StatusOther); 44413182Sgabeblack@google.com scMain->run(); 44513182Sgabeblack@google.com} 44613182Sgabeblack@google.com 44713182Sgabeblack@google.comvoid 44812961Sgabeblack@google.comScheduler::scheduleStop(bool finish_delta) 44912961Sgabeblack@google.com{ 45012961Sgabeblack@google.com if (stopEvent.scheduled()) 45112961Sgabeblack@google.com return; 45212961Sgabeblack@google.com 45312961Sgabeblack@google.com if (!finish_delta) { 45413154Sgabeblack@google.com _stopNow = true; 45513076Sgabeblack@google.com // If we're not supposed to finish the delta cycle, flush all 45613076Sgabeblack@google.com // pending activity. 45713076Sgabeblack@google.com clear(); 45812961Sgabeblack@google.com } 45913088Sgabeblack@google.com schedule(&stopEvent); 46012961Sgabeblack@google.com} 46112961Sgabeblack@google.com 46212953Sgabeblack@google.comScheduler scheduler; 46312953Sgabeblack@google.com 46413182Sgabeblack@google.comnamespace { 46513182Sgabeblack@google.com 46613182Sgabeblack@google.comvoid 46713182Sgabeblack@google.comthrowingReportHandler(const ::sc_core::sc_report &r, 46813182Sgabeblack@google.com const ::sc_core::sc_actions &) 46913182Sgabeblack@google.com{ 47013182Sgabeblack@google.com throw r; 47113182Sgabeblack@google.com} 47213182Sgabeblack@google.com 47313182Sgabeblack@google.com} // anonymous namespace 47413182Sgabeblack@google.com 47513182Sgabeblack@google.comconst ::sc_core::sc_report * 47613182Sgabeblack@google.comreportifyException() 47713182Sgabeblack@google.com{ 47813182Sgabeblack@google.com ::sc_core::sc_report_handler_proc old_handler = 47913182Sgabeblack@google.com ::sc_core::sc_report_handler::get_handler(); 48013182Sgabeblack@google.com ::sc_core::sc_report_handler::set_handler(&throwingReportHandler); 48113182Sgabeblack@google.com 48213182Sgabeblack@google.com try { 48313182Sgabeblack@google.com try { 48413182Sgabeblack@google.com // Rethrow the current exception so we can catch it and throw an 48513182Sgabeblack@google.com // sc_report instead if it's not a type we recognize/can handle. 48613182Sgabeblack@google.com throw; 48713182Sgabeblack@google.com } catch (const ::sc_core::sc_report &) { 48813182Sgabeblack@google.com // It's already a sc_report, so nothing to do. 48913182Sgabeblack@google.com throw; 49013182Sgabeblack@google.com } catch (const ::sc_core::sc_unwind_exception &) { 49113182Sgabeblack@google.com panic("Kill/reset exception escaped a Process::run()"); 49213182Sgabeblack@google.com } catch (const std::exception &e) { 49313182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", e.what()); 49413182Sgabeblack@google.com } catch (const char *msg) { 49513182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", msg); 49613182Sgabeblack@google.com } catch (...) { 49713182Sgabeblack@google.com SC_REPORT_ERROR("uncaught exception", "UNKNOWN EXCEPTION"); 49813182Sgabeblack@google.com } 49913182Sgabeblack@google.com } catch (const ::sc_core::sc_report &r) { 50013182Sgabeblack@google.com ::sc_core::sc_report_handler::set_handler(old_handler); 50113182Sgabeblack@google.com return &r; 50213182Sgabeblack@google.com } 50313182Sgabeblack@google.com panic("No exception thrown in reportifyException."); 50413182Sgabeblack@google.com} 50513182Sgabeblack@google.com 50612953Sgabeblack@google.com} // namespace sc_gem5 507