scheduler.cc revision 13488
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"
3613403Sgabeblack@google.com#include "systemc/core/sc_main_fiber.hh"
3713317Sgabeblack@google.com#include "systemc/ext/core/messages.hh"
3812982Sgabeblack@google.com#include "systemc/ext/core/sc_main.hh"
3913182Sgabeblack@google.com#include "systemc/ext/utils/sc_report.hh"
4013182Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh"
4113312Sgabeblack@google.com#include "systemc/utils/report.hh"
4213245Sgabeblack@google.com#include "systemc/utils/tracefile.hh"
4312953Sgabeblack@google.com
4412953Sgabeblack@google.comnamespace sc_gem5
4512953Sgabeblack@google.com{
4612953Sgabeblack@google.com
4712954Sgabeblack@google.comScheduler::Scheduler() :
4812962Sgabeblack@google.com    eq(nullptr), readyEvent(this, false, ReadyPriority),
4912961Sgabeblack@google.com    pauseEvent(this, false, PausePriority),
5013403Sgabeblack@google.com    stopEvent(this, false, StopPriority), _throwToScMain(nullptr),
5112987Sgabeblack@google.com    starvationEvent(this, false, StarvationPriority),
5213203Sgabeblack@google.com    _elaborationDone(false), _started(false), _stopNow(false),
5313203Sgabeblack@google.com    _status(StatusOther), maxTickEvent(this, false, MaxTickPriority),
5413245Sgabeblack@google.com    timeAdvancesEvent(this, false, TimeAdvancesPriority), _numCycles(0),
5513245Sgabeblack@google.com    _changeStamp(0), _current(nullptr), initDone(false), runOnce(false)
5612954Sgabeblack@google.com{}
5712953Sgabeblack@google.com
5813072Sgabeblack@google.comScheduler::~Scheduler()
5913072Sgabeblack@google.com{
6013072Sgabeblack@google.com    // Clear out everything that belongs to us to make sure nobody tries to
6113072Sgabeblack@google.com    // clear themselves out after the scheduler goes away.
6213076Sgabeblack@google.com    clear();
6313076Sgabeblack@google.com}
6413072Sgabeblack@google.com
6513076Sgabeblack@google.comvoid
6613076Sgabeblack@google.comScheduler::clear()
6713076Sgabeblack@google.com{
6813072Sgabeblack@google.com    // Delta notifications.
6913144Sgabeblack@google.com    while (!deltas.empty())
7013144Sgabeblack@google.com        deltas.front()->deschedule();
7113072Sgabeblack@google.com
7213072Sgabeblack@google.com    // Timed notifications.
7313076Sgabeblack@google.com    for (auto &tsp: timeSlots) {
7413076Sgabeblack@google.com        TimeSlot *&ts = tsp.second;
7513144Sgabeblack@google.com        while (!ts->events.empty())
7613144Sgabeblack@google.com            ts->events.front()->deschedule();
7713088Sgabeblack@google.com        deschedule(ts);
7813072Sgabeblack@google.com    }
7913076Sgabeblack@google.com    timeSlots.clear();
8013072Sgabeblack@google.com
8113072Sgabeblack@google.com    // gem5 events.
8213072Sgabeblack@google.com    if (readyEvent.scheduled())
8313088Sgabeblack@google.com        deschedule(&readyEvent);
8413072Sgabeblack@google.com    if (pauseEvent.scheduled())
8513088Sgabeblack@google.com        deschedule(&pauseEvent);
8613072Sgabeblack@google.com    if (stopEvent.scheduled())
8713088Sgabeblack@google.com        deschedule(&stopEvent);
8813072Sgabeblack@google.com    if (starvationEvent.scheduled())
8913088Sgabeblack@google.com        deschedule(&starvationEvent);
9013072Sgabeblack@google.com    if (maxTickEvent.scheduled())
9113088Sgabeblack@google.com        deschedule(&maxTickEvent);
9213245Sgabeblack@google.com    if (timeAdvancesEvent.scheduled())
9313245Sgabeblack@google.com        deschedule(&timeAdvancesEvent);
9413072Sgabeblack@google.com
9513072Sgabeblack@google.com    Process *p;
9613072Sgabeblack@google.com    while ((p = initList.getNext()))
9713072Sgabeblack@google.com        p->popListNode();
9813176Sgabeblack@google.com    while ((p = readyListMethods.getNext()))
9913176Sgabeblack@google.com        p->popListNode();
10013176Sgabeblack@google.com    while ((p = readyListThreads.getNext()))
10113072Sgabeblack@google.com        p->popListNode();
10213072Sgabeblack@google.com
10313072Sgabeblack@google.com    Channel *c;
10413072Sgabeblack@google.com    while ((c = updateList.getNext()))
10513072Sgabeblack@google.com        c->popListNode();
10613072Sgabeblack@google.com}
10713072Sgabeblack@google.com
10812953Sgabeblack@google.comvoid
10913067Sgabeblack@google.comScheduler::initPhase()
11012953Sgabeblack@google.com{
11113488Sgabeblack@google.com    runUpdate();
11213488Sgabeblack@google.com
11313194Sgabeblack@google.com    for (Process *p = initList.getNext(); p; p = initList.getNext()) {
11412957Sgabeblack@google.com        p->popListNode();
11513180Sgabeblack@google.com
11613194Sgabeblack@google.com        if (p->dontInitialize()) {
11713194Sgabeblack@google.com            if (!p->hasStaticSensitivities() && !p->internal()) {
11813317Sgabeblack@google.com                SC_REPORT_WARNING(sc_core::SC_ID_DISABLE_WILL_ORPHAN_PROCESS_,
11913317Sgabeblack@google.com                        p->name());
12013194Sgabeblack@google.com            }
12113194Sgabeblack@google.com        } else {
12213194Sgabeblack@google.com            p->ready();
12313180Sgabeblack@google.com        }
12412957Sgabeblack@google.com    }
12512957Sgabeblack@google.com
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();
16913328Sgabeblack@google.com        _current->scheduled(false);
17012953Sgabeblack@google.com        // Switch to whatever Fiber is supposed to run this process. All
17112953Sgabeblack@google.com        // Fibers which aren't running should be parked at this line.
17212953Sgabeblack@google.com        _current->fiber()->run();
17312961Sgabeblack@google.com        // If the current process needs to be manually started, start it.
17413093Sgabeblack@google.com        if (_current && _current->needsStart()) {
17513093Sgabeblack@google.com            _current->needsStart(false);
17613308Sgabeblack@google.com            // If a process hasn't started yet, "resetting" it just starts it
17713308Sgabeblack@google.com            // and signals its reset event.
17813308Sgabeblack@google.com            if (_current->inReset())
17913308Sgabeblack@google.com                _current->resetEvent().notify();
18013182Sgabeblack@google.com            try {
18113182Sgabeblack@google.com                _current->run();
18213182Sgabeblack@google.com            } catch (...) {
18313182Sgabeblack@google.com                throwToScMain();
18413182Sgabeblack@google.com            }
18513093Sgabeblack@google.com        }
18612953Sgabeblack@google.com    }
18713259Sgabeblack@google.com    if (_current && !_current->needsStart()) {
18813259Sgabeblack@google.com        if (_current->excWrapper) {
18913259Sgabeblack@google.com            auto ew = _current->excWrapper;
19013259Sgabeblack@google.com            _current->excWrapper = nullptr;
19113259Sgabeblack@google.com            ew->throw_it();
19213260Sgabeblack@google.com        } else if (_current->inReset()) {
19313259Sgabeblack@google.com            _current->reset(false);
19413259Sgabeblack@google.com        }
19512995Sgabeblack@google.com    }
19612953Sgabeblack@google.com}
19712953Sgabeblack@google.com
19812953Sgabeblack@google.comvoid
19912954Sgabeblack@google.comScheduler::ready(Process *p)
20012953Sgabeblack@google.com{
20113154Sgabeblack@google.com    if (_stopNow)
20213154Sgabeblack@google.com        return;
20313154Sgabeblack@google.com
20413328Sgabeblack@google.com    p->scheduled(true);
20513328Sgabeblack@google.com
20613176Sgabeblack@google.com    if (p->procKind() == ::sc_core::SC_METHOD_PROC_)
20713176Sgabeblack@google.com        readyListMethods.pushLast(p);
20812954Sgabeblack@google.com    else
20913176Sgabeblack@google.com        readyListThreads.pushLast(p);
21012953Sgabeblack@google.com
21113244Sgabeblack@google.com    if (!inEvaluate())
21213244Sgabeblack@google.com        scheduleReadyEvent();
21312954Sgabeblack@google.com}
21412954Sgabeblack@google.com
21512954Sgabeblack@google.comvoid
21613133Sgabeblack@google.comScheduler::resume(Process *p)
21713133Sgabeblack@google.com{
21813133Sgabeblack@google.com    if (initDone)
21913133Sgabeblack@google.com        ready(p);
22013133Sgabeblack@google.com    else
22113133Sgabeblack@google.com        initList.pushLast(p);
22213133Sgabeblack@google.com}
22313133Sgabeblack@google.com
22413133Sgabeblack@google.combool
22513176Sgabeblack@google.comlistContains(ListNode *list, ListNode *target)
22613176Sgabeblack@google.com{
22713176Sgabeblack@google.com    ListNode *n = list->nextListNode;
22813176Sgabeblack@google.com    while (n != list)
22913176Sgabeblack@google.com        if (n == target)
23013176Sgabeblack@google.com            return true;
23113176Sgabeblack@google.com    return false;
23213176Sgabeblack@google.com}
23313176Sgabeblack@google.com
23413176Sgabeblack@google.combool
23513133Sgabeblack@google.comScheduler::suspend(Process *p)
23613133Sgabeblack@google.com{
23713176Sgabeblack@google.com    bool was_ready;
23813133Sgabeblack@google.com    if (initDone) {
23913194Sgabeblack@google.com        // After initialization, check if we're on a ready list.
24013176Sgabeblack@google.com        was_ready = (p->nextListNode != nullptr);
24113133Sgabeblack@google.com        p->popListNode();
24213133Sgabeblack@google.com    } else {
24313194Sgabeblack@google.com        // Nothing is ready before init.
24413194Sgabeblack@google.com        was_ready = false;
24513133Sgabeblack@google.com    }
24613176Sgabeblack@google.com    return was_ready;
24713133Sgabeblack@google.com}
24813133Sgabeblack@google.com
24913133Sgabeblack@google.comvoid
25012954Sgabeblack@google.comScheduler::requestUpdate(Channel *c)
25112954Sgabeblack@google.com{
25212954Sgabeblack@google.com    updateList.pushLast(c);
25313244Sgabeblack@google.com    if (!inEvaluate())
25413244Sgabeblack@google.com        scheduleReadyEvent();
25512954Sgabeblack@google.com}
25612954Sgabeblack@google.com
25712954Sgabeblack@google.comvoid
25812954Sgabeblack@google.comScheduler::scheduleReadyEvent()
25912954Sgabeblack@google.com{
26012954Sgabeblack@google.com    // Schedule the evaluate and update phases.
26112954Sgabeblack@google.com    if (!readyEvent.scheduled()) {
26213069Sgabeblack@google.com        schedule(&readyEvent);
26312987Sgabeblack@google.com        if (starvationEvent.scheduled())
26413069Sgabeblack@google.com            deschedule(&starvationEvent);
26512987Sgabeblack@google.com    }
26612987Sgabeblack@google.com}
26712987Sgabeblack@google.com
26812987Sgabeblack@google.comvoid
26912987Sgabeblack@google.comScheduler::scheduleStarvationEvent()
27012987Sgabeblack@google.com{
27112987Sgabeblack@google.com    if (!starvationEvent.scheduled()) {
27213069Sgabeblack@google.com        schedule(&starvationEvent);
27312987Sgabeblack@google.com        if (readyEvent.scheduled())
27413069Sgabeblack@google.com            deschedule(&readyEvent);
27512954Sgabeblack@google.com    }
27612954Sgabeblack@google.com}
27712954Sgabeblack@google.com
27812954Sgabeblack@google.comvoid
27912954Sgabeblack@google.comScheduler::runReady()
28012954Sgabeblack@google.com{
28113245Sgabeblack@google.com    scheduleTimeAdvancesEvent();
28213245Sgabeblack@google.com
28313176Sgabeblack@google.com    bool empty = readyListMethods.empty() && readyListThreads.empty();
28413140Sgabeblack@google.com    lastReadyTick = getCurTick();
28512954Sgabeblack@google.com
28612954Sgabeblack@google.com    // The evaluation phase.
28713245Sgabeblack@google.com    status(StatusEvaluate);
28812953Sgabeblack@google.com    do {
28913209Sgabeblack@google.com        yield();
29013209Sgabeblack@google.com    } while (getNextReady());
29113275Sgabeblack@google.com    _current = nullptr;
29212954Sgabeblack@google.com
29313140Sgabeblack@google.com    if (!empty) {
29412954Sgabeblack@google.com        _numCycles++;
29513140Sgabeblack@google.com        _changeStamp++;
29613140Sgabeblack@google.com    }
29712954Sgabeblack@google.com
29813244Sgabeblack@google.com    if (_stopNow) {
29913244Sgabeblack@google.com        status(StatusOther);
30013154Sgabeblack@google.com        return;
30113244Sgabeblack@google.com    }
30213154Sgabeblack@google.com
30313186Sgabeblack@google.com    runUpdate();
30413245Sgabeblack@google.com    if (!traceFiles.empty())
30513245Sgabeblack@google.com        trace(true);
30613186Sgabeblack@google.com    runDelta();
30713061Sgabeblack@google.com
30813096Sgabeblack@google.com    if (!runToTime && starved())
30913096Sgabeblack@google.com        scheduleStarvationEvent();
31013096Sgabeblack@google.com
31113064Sgabeblack@google.com    if (runOnce)
31213064Sgabeblack@google.com        schedulePause();
31313186Sgabeblack@google.com
31413186Sgabeblack@google.com    status(StatusOther);
31512953Sgabeblack@google.com}
31612953Sgabeblack@google.com
31712953Sgabeblack@google.comvoid
31813186Sgabeblack@google.comScheduler::runUpdate()
31912953Sgabeblack@google.com{
32013186Sgabeblack@google.com    status(StatusUpdate);
32113186Sgabeblack@google.com
32213188Sgabeblack@google.com    try {
32313188Sgabeblack@google.com        Channel *channel = updateList.getNext();
32413188Sgabeblack@google.com        while (channel) {
32513188Sgabeblack@google.com            channel->popListNode();
32613188Sgabeblack@google.com            channel->update();
32713188Sgabeblack@google.com            channel = updateList.getNext();
32813188Sgabeblack@google.com        }
32913188Sgabeblack@google.com    } catch (...) {
33013188Sgabeblack@google.com        throwToScMain();
33112954Sgabeblack@google.com    }
33212953Sgabeblack@google.com}
33312953Sgabeblack@google.com
33412961Sgabeblack@google.comvoid
33513186Sgabeblack@google.comScheduler::runDelta()
33613186Sgabeblack@google.com{
33713186Sgabeblack@google.com    status(StatusDelta);
33813188Sgabeblack@google.com
33913188Sgabeblack@google.com    try {
34013188Sgabeblack@google.com        while (!deltas.empty())
34113289Sgabeblack@google.com            deltas.back()->run();
34213188Sgabeblack@google.com    } catch (...) {
34313188Sgabeblack@google.com        throwToScMain();
34413188Sgabeblack@google.com    }
34513186Sgabeblack@google.com}
34613186Sgabeblack@google.com
34713186Sgabeblack@google.comvoid
34812961Sgabeblack@google.comScheduler::pause()
34912961Sgabeblack@google.com{
35013186Sgabeblack@google.com    status(StatusPaused);
35112982Sgabeblack@google.com    kernel->status(::sc_core::SC_PAUSED);
35213061Sgabeblack@google.com    runOnce = false;
35313403Sgabeblack@google.com    if (scMainFiber.called() && !scMainFiber.finished())
35413403Sgabeblack@google.com        scMainFiber.run();
35512961Sgabeblack@google.com}
35612961Sgabeblack@google.com
35712961Sgabeblack@google.comvoid
35812961Sgabeblack@google.comScheduler::stop()
35912961Sgabeblack@google.com{
36013186Sgabeblack@google.com    status(StatusStopped);
36112982Sgabeblack@google.com    kernel->stop();
36213074Sgabeblack@google.com
36313076Sgabeblack@google.com    clear();
36413074Sgabeblack@google.com
36513061Sgabeblack@google.com    runOnce = false;
36613403Sgabeblack@google.com    if (scMainFiber.called() && !scMainFiber.finished())
36713403Sgabeblack@google.com        scMainFiber.run();
36812961Sgabeblack@google.com}
36912961Sgabeblack@google.com
37012961Sgabeblack@google.comvoid
37112961Sgabeblack@google.comScheduler::start(Tick max_tick, bool run_to_time)
37212961Sgabeblack@google.com{
37312961Sgabeblack@google.com    _started = true;
37413186Sgabeblack@google.com    status(StatusOther);
37512987Sgabeblack@google.com    runToTime = run_to_time;
37612961Sgabeblack@google.com
37712961Sgabeblack@google.com    maxTick = max_tick;
37813140Sgabeblack@google.com    lastReadyTick = getCurTick();
37912961Sgabeblack@google.com
38013067Sgabeblack@google.com    if (initDone) {
38113096Sgabeblack@google.com        if (!runToTime && starved())
38213068Sgabeblack@google.com            scheduleStarvationEvent();
38312982Sgabeblack@google.com        kernel->status(::sc_core::SC_RUNNING);
38412982Sgabeblack@google.com    }
38512961Sgabeblack@google.com
38613069Sgabeblack@google.com    schedule(&maxTickEvent, maxTick);
38713245Sgabeblack@google.com    scheduleTimeAdvancesEvent();
38813069Sgabeblack@google.com
38912961Sgabeblack@google.com    // Return to gem5 to let it run events, etc.
39012961Sgabeblack@google.com    Fiber::primaryFiber()->run();
39112961Sgabeblack@google.com
39212961Sgabeblack@google.com    if (pauseEvent.scheduled())
39313088Sgabeblack@google.com        deschedule(&pauseEvent);
39412961Sgabeblack@google.com    if (stopEvent.scheduled())
39513088Sgabeblack@google.com        deschedule(&stopEvent);
39612961Sgabeblack@google.com    if (maxTickEvent.scheduled())
39713088Sgabeblack@google.com        deschedule(&maxTickEvent);
39812987Sgabeblack@google.com    if (starvationEvent.scheduled())
39913088Sgabeblack@google.com        deschedule(&starvationEvent);
40013182Sgabeblack@google.com
40113182Sgabeblack@google.com    if (_throwToScMain) {
40213182Sgabeblack@google.com        const ::sc_core::sc_report *to_throw = _throwToScMain;
40313182Sgabeblack@google.com        _throwToScMain = nullptr;
40413182Sgabeblack@google.com        throw *to_throw;
40513182Sgabeblack@google.com    }
40612961Sgabeblack@google.com}
40712961Sgabeblack@google.com
40812961Sgabeblack@google.comvoid
40913061Sgabeblack@google.comScheduler::oneCycle()
41013061Sgabeblack@google.com{
41113061Sgabeblack@google.com    runOnce = true;
41213095Sgabeblack@google.com    scheduleReadyEvent();
41313061Sgabeblack@google.com    start(::MaxTick, false);
41413061Sgabeblack@google.com}
41513061Sgabeblack@google.com
41613061Sgabeblack@google.comvoid
41712961Sgabeblack@google.comScheduler::schedulePause()
41812961Sgabeblack@google.com{
41912961Sgabeblack@google.com    if (pauseEvent.scheduled())
42012961Sgabeblack@google.com        return;
42112961Sgabeblack@google.com
42213088Sgabeblack@google.com    schedule(&pauseEvent);
42312961Sgabeblack@google.com}
42412961Sgabeblack@google.com
42512961Sgabeblack@google.comvoid
42613264Sgabeblack@google.comScheduler::throwToScMain()
42713182Sgabeblack@google.com{
42813264Sgabeblack@google.com    ::sc_core::sc_report report = reportifyException();
42913264Sgabeblack@google.com    _throwToScMain = &report;
43013188Sgabeblack@google.com    status(StatusOther);
43113403Sgabeblack@google.com    scMainFiber.run();
43213182Sgabeblack@google.com}
43313182Sgabeblack@google.com
43413182Sgabeblack@google.comvoid
43512961Sgabeblack@google.comScheduler::scheduleStop(bool finish_delta)
43612961Sgabeblack@google.com{
43712961Sgabeblack@google.com    if (stopEvent.scheduled())
43812961Sgabeblack@google.com        return;
43912961Sgabeblack@google.com
44012961Sgabeblack@google.com    if (!finish_delta) {
44113154Sgabeblack@google.com        _stopNow = true;
44213076Sgabeblack@google.com        // If we're not supposed to finish the delta cycle, flush all
44313076Sgabeblack@google.com        // pending activity.
44413076Sgabeblack@google.com        clear();
44512961Sgabeblack@google.com    }
44613088Sgabeblack@google.com    schedule(&stopEvent);
44712961Sgabeblack@google.com}
44812961Sgabeblack@google.com
44913245Sgabeblack@google.comvoid
45013245Sgabeblack@google.comScheduler::trace(bool delta)
45113245Sgabeblack@google.com{
45213245Sgabeblack@google.com    for (auto tf: traceFiles)
45313245Sgabeblack@google.com        tf->trace(delta);
45413245Sgabeblack@google.com}
45513245Sgabeblack@google.com
45612953Sgabeblack@google.comScheduler scheduler;
45713329Sgabeblack@google.comProcess *getCurrentProcess() { return scheduler.current(); }
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) {
48713317Sgabeblack@google.com            SC_REPORT_ERROR(
48813317Sgabeblack@google.com                    sc_core::SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_, e.what());
48913182Sgabeblack@google.com        } catch (const char *msg) {
49013317Sgabeblack@google.com            SC_REPORT_ERROR(
49113317Sgabeblack@google.com                    sc_core::SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_, msg);
49213182Sgabeblack@google.com        } catch (...) {
49313317Sgabeblack@google.com            SC_REPORT_ERROR(
49413317Sgabeblack@google.com                    sc_core::SC_ID_SIMULATION_UNCAUGHT_EXCEPTION_,
49513317Sgabeblack@google.com                    "UNKNOWN EXCEPTION");
49613182Sgabeblack@google.com        }
49713182Sgabeblack@google.com    } catch (const ::sc_core::sc_report &r) {
49813182Sgabeblack@google.com        ::sc_core::sc_report_handler::set_handler(old_handler);
49913264Sgabeblack@google.com        return r;
50013182Sgabeblack@google.com    }
50113182Sgabeblack@google.com    panic("No exception thrown in reportifyException.");
50213182Sgabeblack@google.com}
50313182Sgabeblack@google.com
50412953Sgabeblack@google.com} // namespace sc_gem5
505