From 272a43175fc0de46ba1e264b3b1add5ea01d7e5d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 13 Oct 2019 23:40:04 -0700 Subject: [PATCH] cpu: Switch off of the CPU's comInstEventQueue. 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 Maintainer: Andreas Sandberg Tested-by: kokoro --- src/arch/arm/fastmodel/iris/thread_context.hh | 6 ++++ src/cpu/base.cc | 7 ---- src/cpu/base.hh | 7 ---- src/cpu/checker/thread_context.hh | 22 ++++++++++++ src/cpu/o3/thread_context.hh | 27 ++++++++++++++ src/cpu/o3/thread_state.hh | 11 ++++-- src/cpu/simple_thread.cc | 10 +++--- src/cpu/simple_thread.hh | 32 +++++++++++++++++ src/cpu/thread_context.cc | 35 ------------------- src/cpu/thread_context.hh | 10 +++--- 10 files changed, 106 insertions(+), 61 deletions(-) diff --git a/src/arch/arm/fastmodel/iris/thread_context.hh b/src/arch/arm/fastmodel/iris/thread_context.hh index 13ab29c46..c07c642fb 100644 --- a/src/arch/arm/fastmodel/iris/thread_context.hh +++ b/src/arch/arm/fastmodel/iris/thread_context.hh @@ -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() { diff --git a/src/cpu/base.cc b/src/cpu/base.cc index e8927dfcd..8bdc44eb7 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -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 diff --git a/src/cpu/base.hh b/src/cpu/base.hh index cb23cb1ba..5b15f4186 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -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; /** diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index a7199d168..e45de6e6e 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -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(); } diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 2ec559f2d..e195935c6 100644 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -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 *thread; diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index b2c9296f4..a4a12330f 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -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; diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 0936e41ad..79333cb1b 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -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); diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 86d31b235..5ed0f2982 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -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(); } diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc index 1250a3e4c..dea39015f 100644 --- a/src/cpu/thread_context.cc +++ b/src/cpu/thread_context.cc @@ -55,41 +55,6 @@ #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) { diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index a6793a263..16310649c 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -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 -- 2.30.2