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 <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2019-10-13 23:40:04 -07:00
parent a2a8dac5c2
commit 272a43175f
10 changed files with 106 additions and 61 deletions

View 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()
{

View 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

View 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;
/**

View 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(); }

View 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;

View 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;

View 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);

View 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(); }

View File

@@ -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)
{

View 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