cpu: Switch off of the CPU's comInstEventQueue.
authorGabe Black <gabeblack@google.com>
Mon, 14 Oct 2019 06:40:04 +0000 (23:40 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 25 Oct 2019 22:42:31 +0000 (22:42 +0000)
This switches to letting the ThreadContexts use a thread based/local
comInstEventQueue instead of falling back to the CPU's array. Because
the implementation is no longer shared and it's not given where the
comInstEventQueue (or other implementation) should be accessed, the
default implementation has been removed.

Also, because nobody is using the CPU's array of event queues, those
have been removed.

Change-Id: I515e6e00a2174067a928c33ef832bc5c840bdf7f
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22110
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/fastmodel/iris/thread_context.hh
src/cpu/base.cc
src/cpu/base.hh
src/cpu/checker/thread_context.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_state.hh
src/cpu/simple_thread.cc
src/cpu/simple_thread.hh
src/cpu/thread_context.cc
src/cpu/thread_context.hh

index 13ab29c468a77bdb28dd90a843fb7f70572defbd..c07c642fbd6ee7f25057f84e6abd0c4a23166dbd 100644 (file)
@@ -96,6 +96,12 @@ class ThreadContext : public ::ThreadContext
     bool schedule(PCEvent *e) override { return false; }
     bool remove(PCEvent *e) override { return false; }
 
+    Tick nextInstEventCount() override { return MaxTick; }
+    void serviceInstCountEvents(Tick count) override {}
+    void scheduleInstCountEvent(Event *event, Tick count) override {}
+    void descheduleInstCountEvent(Event *event) override {}
+    Tick getCurrentInstCount() override { return 0; }
+
     virtual Counter
     totalInsts()
     {
index e8927dfcd3b28534af054c809b52139634530726..8bdc44eb79fab348e42ef7a8893ecbddf3112be4 100644 (file)
@@ -156,12 +156,6 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
     if (numThreads > maxThreadsPerCPU)
         maxThreadsPerCPU = numThreads;
 
-    // allocate per-thread instruction-based event queues
-    comInstEventQueue = new EventQueue *[numThreads];
-    for (ThreadID tid = 0; tid < numThreads; ++tid)
-        comInstEventQueue[tid] =
-            new EventQueue("instruction-based event queue");
-
     functionTracingEnabled = false;
     if (p->function_trace) {
         const string fname = csprintf("ftrace.%s", name());
@@ -213,7 +207,6 @@ BaseCPU::enableFunctionTrace()
 BaseCPU::~BaseCPU()
 {
     delete profileEvent;
-    delete[] comInstEventQueue;
 }
 
 void
index cb23cb1ba72cf2a00d57a1c7e67bcebb7ef81c68..5b15f41860d3c3ec9a974a538e225bf068b05a08 100644 (file)
@@ -383,13 +383,6 @@ class BaseCPU : public ClockedObject
      */
     ThreadID numThreads;
 
-    /**
-     * Vector of per-thread instruction-based event queues.  Used for
-     * scheduling events based on number of instructions committed by
-     * a particular thread.
-     */
-    EventQueue **comInstEventQueue;
-
     System *system;
 
     /**
index a7199d16802c90aa8ed6f3ecf03ad701c09ce176..e45de6e6eaad7fcbef9c2dbe698d71e48f4e5bd2 100644 (file)
@@ -92,6 +92,28 @@ class CheckerThreadContext : public ThreadContext
     bool schedule(PCEvent *e) override { return actualTC->schedule(e); }
     bool remove(PCEvent *e) override { return actualTC->remove(e); }
 
+    Tick
+    nextInstEventCount() override
+    {
+        return actualTC->nextInstEventCount();
+    }
+    void
+    serviceInstCountEvents(Tick count) override
+    {
+        actualTC->serviceInstCountEvents(count);
+    }
+    void
+    scheduleInstCountEvent(Event *event, Tick count) override
+    {
+        actualTC->scheduleInstCountEvent(event, count);
+    }
+    void
+    descheduleInstCountEvent(Event *event) override
+    {
+        actualTC->descheduleInstCountEvent(event);
+    }
+    Tick getCurrentInstCount() override { return getCurrentInstCount(); }
+
     BaseCPU *getCpuPtr() override { return actualTC->getCpuPtr(); }
 
     uint32_t socketId() const override { return actualTC->socketId(); }
index 2ec559f2de3b282d8daaa124c18b2984c1a18071..e195935c680bb8d449f8028fcd978cc2cd5a54fe 100644 (file)
@@ -86,6 +86,33 @@ class O3ThreadContext : public ThreadContext
         return thread->pcEventQueue.remove(e);
     }
 
+    Tick
+    nextInstEventCount() override
+    {
+        return thread->comInstEventQueue.empty() ?
+            MaxTick : thread->comInstEventQueue.nextTick();
+    }
+    void
+    serviceInstCountEvents(Tick count) override
+    {
+        thread->comInstEventQueue.serviceEvents(count);
+    }
+    void
+    scheduleInstCountEvent(Event *event, Tick count) override
+    {
+        thread->comInstEventQueue.schedule(event, count);
+    }
+    void
+    descheduleInstCountEvent(Event *event) override
+    {
+        thread->comInstEventQueue.deschedule(event);
+    }
+    Tick
+    getCurrentInstCount() override
+    {
+        return thread->comInstEventQueue.getCurTick();
+    }
+
     /** Pointer to the thread state that this TC corrseponds to. */
     O3ThreadState<Impl> *thread;
 
index b2c9296f466596b0c0fb1391302a8a531704850e..a4a12330f322895978087e74d24b8d96bba6e324 100644 (file)
@@ -75,6 +75,11 @@ struct O3ThreadState : public ThreadState {
 
   public:
     PCEventQueue pcEventQueue;
+    /**
+     * An instruction-based event queue. Used for scheduling events based on
+     * number of instructions committed.
+     */
+    EventQueue comInstEventQueue;
 
     /* This variable controls if writes to a thread context should cause a all
      * dynamic/speculative state to be thrown away. Nominally this is the
@@ -92,9 +97,9 @@ struct O3ThreadState : public ThreadState {
     bool trapPending;
 
     O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process)
-        : ThreadState(_cpu, _thread_num, _process),
-          cpu(_cpu), noSquashFromTC(false), trapPending(false),
-          tc(nullptr)
+        : ThreadState(_cpu, _thread_num, _process), cpu(_cpu),
+          comInstEventQueue("instruction-based event queue"),
+          noSquashFromTC(false), trapPending(false), tc(nullptr)
     {
         if (!FullSystem)
             return;
index 0936e41ad1d48f293b3884c7cc0335c4b6820b52..79333cb1b3d4d7b53d059b7f349109a8848440d0 100644 (file)
@@ -77,8 +77,9 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
                            Process *_process, BaseTLB *_itb,
                            BaseTLB *_dtb, TheISA::ISA *_isa)
     : ThreadState(_cpu, _thread_num, _process), isa(_isa),
-      predicate(true), memAccPredicate(true), system(_sys),
-      itb(_itb), dtb(_dtb), decoder(TheISA::Decoder(_isa))
+      predicate(true), memAccPredicate(true),
+      comInstEventQueue("instruction-based event queue"),
+      system(_sys), itb(_itb), dtb(_dtb), decoder(TheISA::Decoder(_isa))
 {
     clearArchRegs();
     quiesceEvent = new EndQuiesceEvent(this);
@@ -88,8 +89,9 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
                            BaseTLB *_itb, BaseTLB *_dtb,
                            TheISA::ISA *_isa, bool use_kernel_stats)
     : ThreadState(_cpu, _thread_num, NULL), isa(_isa),
-      predicate(true), memAccPredicate(true), system(_sys),
-      itb(_itb), dtb(_dtb), decoder(TheISA::Decoder(_isa))
+      predicate(true), memAccPredicate(true),
+      comInstEventQueue("instruction-based event queue"),
+      system(_sys), itb(_itb), dtb(_dtb), decoder(TheISA::Decoder(_isa))
 {
     quiesceEvent = new EndQuiesceEvent(this);
 
index 86d31b2352dbb1c9e8d0004e5cb392420253253c..5ed0f2982ab6370feb0a26d5cc91180770642aab 100644 (file)
@@ -127,6 +127,11 @@ class SimpleThread : public ThreadState, public ThreadContext
     }
 
     PCEventQueue pcEventQueue;
+    /**
+     * An instruction-based event queue. Used for scheduling events based on
+     * number of instructions committed.
+     */
+    EventQueue comInstEventQueue;
 
     System *system;
 
@@ -193,6 +198,33 @@ class SimpleThread : public ThreadState, public ThreadContext
     bool schedule(PCEvent *e) override { return pcEventQueue.schedule(e); }
     bool remove(PCEvent *e) override { return pcEventQueue.remove(e); }
 
+    Tick
+    nextInstEventCount() override
+    {
+        return comInstEventQueue.empty() ?
+            MaxTick : comInstEventQueue.nextTick();
+    }
+    void
+    serviceInstCountEvents(Tick count) override
+    {
+        comInstEventQueue.serviceEvents(count);
+    }
+    void
+    scheduleInstCountEvent(Event *event, Tick count) override
+    {
+        comInstEventQueue.schedule(event, count);
+    }
+    void
+    descheduleInstCountEvent(Event *event) override
+    {
+        comInstEventQueue.deschedule(event);
+    }
+    Tick
+    getCurrentInstCount() override
+    {
+        return comInstEventQueue.getCurTick();
+    }
+
     BaseCPU *getCpuPtr() override { return baseCpu; }
 
     int cpuId() const override { return ThreadState::cpuId(); }
index 1250a3e4cb376a06a74c58d1194a4ea623d9f409..dea39015f107942eb3aecc612f02bc0401a35db0 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 a6793a26318aa93a87c1a3b8ec5e45ce927a7e9d..16310649cee72731bb02835afc8e7937105df02d 100644 (file)
@@ -192,11 +192,11 @@ 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();
+    virtual Tick nextInstEventCount() = 0;
+    virtual void serviceInstCountEvents(Tick count) = 0;
+    virtual void scheduleInstCountEvent(Event *event, Tick count) = 0;
+    virtual void descheduleInstCountEvent(Event *event) = 0;
+    virtual Tick getCurrentInstCount() = 0;
 
     // Not necessarily the best location for these...
     // Having an extra function just to read these is obnoxious