cpu: Make the ThreadContext a PCEventScope.
Both the thread and system's PCEventQueue are checked when appropriate. Change-Id: I16c371339c91a37b5641860d974e546a30e23e13 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22105 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -93,6 +93,9 @@ class ThreadContext : public ::ThreadContext
|
||||
const std::string &iris_path);
|
||||
virtual ~ThreadContext();
|
||||
|
||||
bool schedule(PCEvent *e) override { return false; }
|
||||
bool remove(PCEvent *e) override { return false; }
|
||||
|
||||
virtual Counter
|
||||
totalInsts()
|
||||
{
|
||||
|
||||
@@ -413,6 +413,7 @@ Checker<Impl>::verify(const DynInstPtr &completed_inst)
|
||||
do {
|
||||
oldpc = thread->instAddr();
|
||||
system->pcEventQueue.service(oldpc, tc);
|
||||
thread->pcEventQueue.service(oldpc, tc);
|
||||
count++;
|
||||
} while (oldpc != thread->instAddr());
|
||||
if (count > 1) {
|
||||
|
||||
@@ -89,6 +89,8 @@ class CheckerThreadContext : public ThreadContext
|
||||
CheckerCPU *checkerCPU;
|
||||
|
||||
public:
|
||||
bool schedule(PCEvent *e) override { return actualTC->schedule(e); }
|
||||
bool remove(PCEvent *e) override { return actualTC->remove(e); }
|
||||
|
||||
BaseCPU *getCpuPtr() override { return actualTC->getCpuPtr(); }
|
||||
|
||||
|
||||
@@ -842,6 +842,7 @@ Execute::tryPCEvents(ThreadID thread_id)
|
||||
do {
|
||||
oldPC = thread->instAddr();
|
||||
cpu.system->pcEventQueue.service(oldPC, thread);
|
||||
cpu.threads[thread_id]->pcEventQueue.service(oldPC, thread);
|
||||
num_pc_event_checks++;
|
||||
} while (oldPC != thread->instAddr());
|
||||
|
||||
|
||||
@@ -1114,6 +1114,8 @@ DefaultCommit<Impl>::commitInsts()
|
||||
oldpc = pc[tid].instAddr();
|
||||
cpu->system->pcEventQueue.service(
|
||||
oldpc, thread[tid]->getTC());
|
||||
thread[tid]->pcEventQueue.service(
|
||||
oldpc, thread[tid]->getTC());
|
||||
count++;
|
||||
} while (oldpc != pc[tid].instAddr());
|
||||
if (count > 1) {
|
||||
|
||||
@@ -75,6 +75,17 @@ class O3ThreadContext : public ThreadContext
|
||||
/** Pointer to the CPU. */
|
||||
O3CPU *cpu;
|
||||
|
||||
bool
|
||||
schedule(PCEvent *e) override
|
||||
{
|
||||
return thread->pcEventQueue.schedule(e);
|
||||
}
|
||||
bool
|
||||
remove(PCEvent *e) override
|
||||
{
|
||||
return thread->pcEventQueue.remove(e);
|
||||
}
|
||||
|
||||
/** Pointer to the thread state that this TC corrseponds to. */
|
||||
O3ThreadState<Impl> *thread;
|
||||
|
||||
|
||||
@@ -72,7 +72,10 @@ struct O3ThreadState : public ThreadState {
|
||||
private:
|
||||
/** Pointer to the CPU. */
|
||||
O3CPU *cpu;
|
||||
|
||||
public:
|
||||
PCEventQueue pcEventQueue;
|
||||
|
||||
/* This variable controls if writes to a thread context should cause a all
|
||||
* dynamic/speculative state to be thrown away. Nominally this is the
|
||||
* desired behavior because the external thread context write has updated
|
||||
|
||||
@@ -145,6 +145,8 @@ BaseSimpleCPU::checkPcEventQueue()
|
||||
do {
|
||||
oldpc = pc;
|
||||
system->pcEventQueue.service(oldpc, threadContexts[curThread]);
|
||||
threadInfo[curThread]->thread->pcEventQueue.service(
|
||||
oldpc, threadContexts[curThread]);
|
||||
pc = threadInfo[curThread]->thread->instAddr();
|
||||
} while (oldpc != pc);
|
||||
}
|
||||
|
||||
@@ -126,6 +126,8 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
return csprintf("%s.[tid:%i]", baseCpu->name(), threadId());
|
||||
}
|
||||
|
||||
PCEventQueue pcEventQueue;
|
||||
|
||||
System *system;
|
||||
|
||||
BaseTLB *itb;
|
||||
@@ -188,6 +190,9 @@ class SimpleThread : public ThreadState, public ThreadContext
|
||||
* ThreadContext interface functions.
|
||||
******************************************/
|
||||
|
||||
bool schedule(PCEvent *e) override { return pcEventQueue.schedule(e); }
|
||||
bool remove(PCEvent *e) override { return pcEventQueue.remove(e); }
|
||||
|
||||
BaseCPU *getCpuPtr() override { return baseCpu; }
|
||||
|
||||
int cpuId() const override { return ThreadState::cpuId(); }
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "arch/types.hh"
|
||||
#include "base/types.hh"
|
||||
#include "config/the_isa.hh"
|
||||
#include "cpu/pc_event.hh"
|
||||
#include "cpu/reg_class.hh"
|
||||
|
||||
// @todo: Figure out a more architecture independent way to obtain the ITB and
|
||||
@@ -88,7 +89,7 @@ namespace Kernel {
|
||||
* interface; the ExecContext is a more implicit interface that must
|
||||
* be implemented so that the ISA can access whatever state it needs.
|
||||
*/
|
||||
class ThreadContext
|
||||
class ThreadContext : public PCEventScope
|
||||
{
|
||||
protected:
|
||||
typedef TheISA::MachInst MachInst;
|
||||
|
||||
Reference in New Issue
Block a user