summaryrefslogtreecommitdiff
path: root/src/systemc/core/scheduler.hh
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-07-18 20:59:56 -0700
committerGabe Black <gabeblack@google.com>2018-09-05 06:09:21 +0000
commit743a1b5cdd8e607f2e1bb5ad182047c512eae3f8 (patch)
tree646432533f331db140547ac1cb4f60feda5928bd /src/systemc/core/scheduler.hh
parent91a6b128198515a7a29ee766715c9a1fe1bf7b0c (diff)
downloadgem5-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.hh72
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;