cpu: Delegate comInstEventQueue methods to the ThreadContexts.
authorGabe Black <gabeblack@google.com>
Mon, 14 Oct 2019 05:54:11 +0000 (22:54 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 25 Oct 2019 22:42:31 +0000 (22:42 +0000)
These then just use the comInstEventQueue array from the CPU, but soon
they will actually be self contained and allow the thread context to
use whatever mechanism it wants.

Also, now that the thread contexts need to exist before instruction
count based events can be scheduled, setting up max instruction based
events needs to happen in init after the CPU subclasses have had a
chance to set up the threadContexts vector.

Change-Id: I34bb401633d277a60be74e30d5a478a149b972ea
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22108
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/cpu/base.cc
src/cpu/base.hh
src/cpu/thread_context.cc
src/cpu/thread_context.hh

index a4ffb1031a0b78a5aea6641cb9276e276ea08bba..7040cb7ea0e08af7e34969a6b6ccdd99e3c3b676 100644 (file)
@@ -162,43 +162,6 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
         comInstEventQueue[tid] =
             new EventQueue("instruction-based event queue");
 
-    //
-    // set up instruction-count-based termination events, if any
-    //
-    if (p->max_insts_any_thread != 0) {
-        const char *cause = "a thread reached the max instruction count";
-        for (ThreadID tid = 0; tid < numThreads; ++tid)
-            scheduleInstStop(tid, p->max_insts_any_thread, cause);
-    }
-
-    // Set up instruction-count-based termination events for SimPoints
-    // Typically, there are more than one action points.
-    // Simulation.py is responsible to take the necessary actions upon
-    // exitting the simulation loop.
-    if (!p->simpoint_start_insts.empty()) {
-        const char *cause = "simpoint starting point found";
-        for (size_t i = 0; i < p->simpoint_start_insts.size(); ++i)
-            scheduleInstStop(0, p->simpoint_start_insts[i], cause);
-    }
-
-    if (p->max_insts_all_threads != 0) {
-        const char *cause = "all threads reached the max instruction count";
-
-        // allocate & initialize shared downcounter: each event will
-        // decrement this when triggered; simulation will terminate
-        // when counter reaches 0
-        int *counter = new int;
-        *counter = numThreads;
-        for (ThreadID tid = 0; tid < numThreads; ++tid) {
-            Event *event = new CountedExitEvent(cause, *counter);
-            scheduleInstCountEvent(tid, event, p->max_insts_all_threads);
-        }
-    }
-
-    //
-    // set up instruction-count-based termination events, if any
-    //
-
     functionTracingEnabled = false;
     if (p->function_trace) {
         const string fname = csprintf("ftrace.%s", name());
@@ -323,6 +286,39 @@ BaseCPU::mwaitAtomic(ThreadID tid, ThreadContext *tc, BaseTLB *dtb)
 void
 BaseCPU::init()
 {
+    // Set up instruction-count-based termination events, if any. This needs
+    // to happen after threadContexts has been constructed.
+    if (params()->max_insts_any_thread != 0) {
+        const char *cause = "a thread reached the max instruction count";
+        for (ThreadID tid = 0; tid < numThreads; ++tid)
+            scheduleInstStop(tid, params()->max_insts_any_thread, cause);
+    }
+
+    // Set up instruction-count-based termination events for SimPoints
+    // Typically, there are more than one action points.
+    // Simulation.py is responsible to take the necessary actions upon
+    // exitting the simulation loop.
+    if (!params()->simpoint_start_insts.empty()) {
+        const char *cause = "simpoint starting point found";
+        for (size_t i = 0; i < params()->simpoint_start_insts.size(); ++i)
+            scheduleInstStop(0, params()->simpoint_start_insts[i], cause);
+    }
+
+    if (params()->max_insts_all_threads != 0) {
+        const char *cause = "all threads reached the max instruction count";
+
+        // allocate & initialize shared downcounter: each event will
+        // decrement this when triggered; simulation will terminate
+        // when counter reaches 0
+        int *counter = new int;
+        *counter = numThreads;
+        for (ThreadID tid = 0; tid < numThreads; ++tid) {
+            Event *event = new CountedExitEvent(cause, *counter);
+            scheduleInstCountEvent(
+                    tid, event, params()->max_insts_all_threads);
+        }
+    }
+
     if (!params()->switched_out) {
         registerThreadContexts();
 
@@ -735,7 +731,7 @@ BaseCPU::scheduleInstStop(ThreadID tid, Counter insts, const char *cause)
 Tick
 BaseCPU::getCurrentInstCount(ThreadID tid)
 {
-    return comInstEventQueue[tid]->getCurTick();
+    return threadContexts[tid]->getCurrentInstCount();
 }
 
 AddressMonitor::AddressMonitor() {
index 0424945cb296022e32a3d044d5bec6934f345140..d73f4a2d563a57af8be6c65b028ff4bfc26b291d 100644 (file)
@@ -468,26 +468,25 @@ class BaseCPU : public ClockedObject
     Tick
     nextInstEventCount(ThreadID tid)
     {
-        return comInstEventQueue[tid]->empty() ?
-            MaxTick : comInstEventQueue[tid]->nextTick();
+        return threadContexts[tid]->nextInstEventCount();
     }
 
     void
     serviceInstCountEvents(ThreadID tid, Tick count)
     {
-        comInstEventQueue[tid]->serviceEvents(count);
+        threadContexts[tid]->serviceInstCountEvents(count);
     }
 
     void
     scheduleInstCountEvent(ThreadID tid, Event *event, Tick count)
     {
-        comInstEventQueue[tid]->schedule(event, count);
+        threadContexts[tid]->scheduleInstCountEvent(event, count);
     }
 
     void
     descheduleInstCountEvent(ThreadID tid, Event *event)
     {
-        comInstEventQueue[tid]->deschedule(event);
+        threadContexts[tid]->descheduleInstCountEvent(event);
     }
 
   public:
index dea39015f107942eb3aecc612f02bc0401a35db0..1250a3e4cb376a06a74c58d1194a4ea623d9f409 100644 (file)
 #include "params/BaseCPU.hh"
 #include "sim/full_system.hh"
 
+Tick
+ThreadContext::nextInstEventCount()
+{
+    auto *queue = getCpuPtr()->comInstEventQueue[threadId()];
+    return queue->empty() ? MaxTick : queue->nextTick();
+}
+
+void
+ThreadContext::serviceInstCountEvents(Tick count)
+{
+    auto *queue = getCpuPtr()->comInstEventQueue[threadId()];
+    queue->serviceEvents(count);
+}
+
+void
+ThreadContext::scheduleInstCountEvent(Event *event, Tick count)
+{
+    auto *queue = getCpuPtr()->comInstEventQueue[threadId()];
+    return queue->schedule(event, count);
+}
+
+void
+ThreadContext::descheduleInstCountEvent(Event *event)
+{
+    auto *queue = getCpuPtr()->comInstEventQueue[threadId()];
+    queue->deschedule(event);
+}
+
+Tick
+ThreadContext::getCurrentInstCount()
+{
+    auto *queue = getCpuPtr()->comInstEventQueue[threadId()];
+    return queue->getCurTick();
+}
+
 void
 ThreadContext::compare(ThreadContext *one, ThreadContext *two)
 {
index 749b4ca90a1cfba671d71dbecaecfbed6a7e3017..a6793a26318aa93a87c1a3b8ec5e45ce927a7e9d 100644 (file)
@@ -192,6 +192,12 @@ class ThreadContext : public PCEventScope
 
     virtual EndQuiesceEvent *getQuiesceEvent() = 0;
 
+    virtual Tick nextInstEventCount();
+    virtual void serviceInstCountEvents(Tick count);
+    virtual void scheduleInstCountEvent(Event *event, Tick count);
+    virtual void descheduleInstCountEvent(Event *event);
+    virtual Tick getCurrentInstCount();
+
     // Not necessarily the best location for these...
     // Having an extra function just to read these is obnoxious
     virtual Tick readLastActivate() = 0;