diff options
author | Gabe Black <gabeblack@google.com> | 2018-07-18 20:59:56 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-09-05 06:09:21 +0000 |
commit | 743a1b5cdd8e607f2e1bb5ad182047c512eae3f8 (patch) | |
tree | 646432533f331db140547ac1cb4f60feda5928bd /src/systemc/core/scheduler.hh | |
parent | 91a6b128198515a7a29ee766715c9a1fe1bf7b0c (diff) | |
download | gem5-743a1b5cdd8e607f2e1bb5ad182047c512eae3f8.tar.xz |
systemc: Implement pending activity related functions
Track the number of notifications/timeouts that are scheduled at any
given time. This lets us implement sc_pending_activity_at_current_time,
sc_pending_activity_at_future_time, and sc_time_to_pending_activity.
Change-Id: Ia3fcd29bdbfe1a6c77eb52ce4836982d4705263c
Reviewed-on: https://gem5-review.googlesource.com/12032
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/core/scheduler.hh')
-rw-r--r-- | src/systemc/core/scheduler.hh | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh index 5db5556ae..3ac7f419f 100644 --- a/src/systemc/core/scheduler.hh +++ b/src/systemc/core/scheduler.hh @@ -179,8 +179,75 @@ class Scheduler // Set an event queue for scheduling events. void setEventQueue(EventQueue *_eq) { eq = _eq; } - // Retrieve the event queue. - EventQueue &eventQueue() const { return *eq; } + // Get the current time according to gem5. + Tick getCurTick() { return eq ? eq->getCurTick() : 0; } + + // For scheduling delayed/timed notifications/timeouts. + void + schedule(::Event *event, Tick tick) + { + pendingTicks[tick]++; + eq->schedule(event, tick); + } + + // For descheduling delayed/timed notifications/timeouts. + void + deschedule(::Event *event) + { + auto it = pendingTicks.find(event->when()); + if (--it->second == 0) + pendingTicks.erase(it); + eq->deschedule(event); + } + + // Tell the scheduler than an event fired for bookkeeping purposes. + void + eventHappened() + { + auto it = pendingTicks.begin(); + if (--it->second == 0) + pendingTicks.erase(it); + } + + // Pending activity ignores gem5 activity, much like how a systemc + // simulation wouldn't know about asynchronous external events (socket IO + // for instance) that might happen before time advances in a pure + // systemc simulation. Also the spec lists what specific types of pending + // activity needs to be counted, which obviously doesn't include gem5 + // events. + + // Return whether there's pending systemc activity at this time. + bool + pendingCurr() + { + if (!readyList.empty() || !updateList.empty()) + return true; + return pendingTicks.size() && + pendingTicks.begin()->first == getCurTick(); + } + + // Return whether there are pending timed notifications or timeouts. + bool + pendingFuture() + { + switch (pendingTicks.size()) { + case 0: return false; + case 1: return pendingTicks.begin()->first > getCurTick(); + default: return true; + } + } + + // Return how many ticks there are until the first pending event, if any. + Tick + timeToPending() + { + if (!readyList.empty() || !updateList.empty()) + return 0; + else if (pendingTicks.size()) + return pendingTicks.begin()->first - getCurTick(); + else + return MaxTick - getCurTick(); + } // Run scheduled channel updates. void update(); @@ -205,6 +272,7 @@ class Scheduler static Priority MaxTickPriority = DefaultPriority + 3; EventQueue *eq; + std::map<Tick, int> pendingTicks; void runReady(); EventWrapper<Scheduler, &Scheduler::runReady> readyEvent; |