cpu: Refactor some Event subclasses to lambdas

Change-Id: If765c6100d67556f157e4e61aa33c2b7eeb8d2f0
Signed-off-by: Sean Wilson <spwilson2@wisc.edu>
Reviewed-on: https://gem5-review.googlesource.com/3923
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
Sean Wilson
2017-06-28 08:52:08 -05:00
parent 741261f10b
commit 8c1ea47b3c
10 changed files with 30 additions and 138 deletions

View File

@@ -248,7 +248,9 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
if (FullSystem) {
if (params()->profile)
profileEvent = new ProfileEvent(this, params()->profile);
profileEvent = new EventFunctionWrapper(
[this]{ processProfileEvent(); },
name());
}
tracer = params()->tracer;
@@ -658,21 +660,15 @@ BaseCPU::flushTLBs()
}
}
BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, Tick _interval)
: cpu(_cpu), interval(_interval)
{ }
void
BaseCPU::ProfileEvent::process()
BaseCPU::processProfileEvent()
{
ThreadID size = cpu->threadContexts.size();
for (ThreadID i = 0; i < size; ++i) {
ThreadContext *tc = cpu->threadContexts[i];
tc->profileSample();
}
ThreadID size = threadContexts.size();
cpu->schedule(this, curTick() + interval);
for (ThreadID i = 0; i < size; ++i)
threadContexts[i]->profileSample();
schedule(profileEvent, curTick() + params()->profile);
}
void

View File

@@ -248,17 +248,8 @@ class BaseCPU : public MemObject
return FullSystem && interrupts[tc->threadId()]->checkInterrupts(tc);
}
class ProfileEvent : public Event
{
private:
BaseCPU *cpu;
Tick interval;
public:
ProfileEvent(BaseCPU *cpu, Tick interval);
void process();
};
ProfileEvent *profileEvent;
void processProfileEvent();
EventFunctionWrapper * profileEvent;
protected:
std::vector<ThreadContext *> threadContexts;

View File

@@ -321,7 +321,8 @@ LSQ::SplitDataRequest::finish(const Fault &fault_, RequestPtr request_,
LSQ::SplitDataRequest::SplitDataRequest(LSQ &port_, MinorDynInstPtr inst_,
bool isLoad_, PacketDataPtr data_, uint64_t *res_) :
LSQRequest(port_, inst_, isLoad_, data_, res_),
translationEvent(*this),
translationEvent([this]{ sendNextFragmentToTranslation(); },
"translationEvent"),
numFragments(0),
numInTranslationFragments(0),
numTranslatedFragments(0),

View File

@@ -377,20 +377,7 @@ class LSQ : public Named
{
protected:
/** Event to step between translations */
class TranslationEvent : public Event
{
protected:
SplitDataRequest &owner;
public:
TranslationEvent(SplitDataRequest &owner_)
: owner(owner_) { }
void process()
{ owner.sendNextFragmentToTranslation(); }
};
TranslationEvent translationEvent;
EventFunctionWrapper translationEvent;
protected:
/** Number of fragments this request is split into */
unsigned int numFragments;

View File

@@ -101,21 +101,6 @@ class DefaultCommit
typedef O3ThreadState<Impl> Thread;
/** Event class used to schedule a squash due to a trap (fault or
* interrupt) to happen on a specific cycle.
*/
class TrapEvent : public Event {
private:
DefaultCommit<Impl> *commit;
ThreadID tid;
public:
TrapEvent(DefaultCommit<Impl> *_commit, ThreadID _tid);
void process();
const char *description() const;
};
/** Overall commit status. Used to determine if the CPU can deschedule
* itself due to a lack of activity.
*/
@@ -157,6 +142,9 @@ class DefaultCommit
/** To probe when an instruction is squashed */
ProbePointArg<DynInstPtr> *ppSquash;
/** Mark the thread as processing a trap. */
void processTrapEvent(ThreadID tid);
public:
/** Construct a DefaultCommit with the given parameters. */
DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params);

View File

@@ -70,27 +70,13 @@
using namespace std;
template <class Impl>
DefaultCommit<Impl>::TrapEvent::TrapEvent(DefaultCommit<Impl> *_commit,
ThreadID _tid)
: Event(CPU_Tick_Pri, AutoDelete), commit(_commit), tid(_tid)
{
}
template <class Impl>
void
DefaultCommit<Impl>::TrapEvent::process()
DefaultCommit<Impl>::processTrapEvent(ThreadID tid)
{
// This will get reset by commit if it was switched out at the
// time of this event processing.
commit->trapSquash[tid] = true;
}
template <class Impl>
const char *
DefaultCommit<Impl>::TrapEvent::description() const
{
return "Trap";
trapSquash[tid] = true;
}
template <class Impl>
@@ -537,7 +523,9 @@ DefaultCommit<Impl>::generateTrapEvent(ThreadID tid, Fault inst_fault)
{
DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
TrapEvent *trap = new TrapEvent(this, tid);
EventFunctionWrapper *trap = new EventFunctionWrapper(
[this, tid]{ processTrapEvent(tid); },
"Trap", true, Event::CPU_Tick_Pri);
Cycles latency = dynamic_pointer_cast<SyscallRetryFault>(inst_fault) ?
cpu->syscallRetryLatency : trapLatency;

View File

@@ -136,32 +136,13 @@ FullO3CPU<Impl>::DcachePort::recvReqRetry()
lsq->recvReqRetry();
}
template <class Impl>
FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
: Event(CPU_Tick_Pri), cpu(c)
{
}
template <class Impl>
void
FullO3CPU<Impl>::TickEvent::process()
{
cpu->tick();
}
template <class Impl>
const char *
FullO3CPU<Impl>::TickEvent::description() const
{
return "FullO3CPU tick";
}
template <class Impl>
FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
: BaseO3CPU(params),
itb(params->itb),
dtb(params->dtb),
tickEvent(this),
tickEvent([this]{ tick(); }, "FullO3CPU tick",
false, Event::CPU_Tick_Pri),
#ifndef NDEBUG
instcount(0),
#endif

View File

@@ -199,24 +199,8 @@ class FullO3CPU : public BaseO3CPU
virtual bool isSnooping() const { return true; }
};
class TickEvent : public Event
{
private:
/** Pointer to the CPU. */
FullO3CPU<Impl> *cpu;
public:
/** Constructs a tick event. */
TickEvent(FullO3CPU<Impl> *c);
/** Processes a tick event, calling tick() on the CPU. */
void process();
/** Returns the description of the tick event. */
const char *description() const;
};
/** The tick event used for scheduling CPU ticks. */
TickEvent tickEvent;
EventFunctionWrapper tickEvent;
/** Schedule tick event, regardless of its current state. */
void scheduleTickEvent(Cycles delay)

View File

@@ -64,24 +64,6 @@
using namespace std;
using namespace TheISA;
AtomicSimpleCPU::TickEvent::TickEvent(AtomicSimpleCPU *c)
: Event(CPU_Tick_Pri), cpu(c)
{
}
void
AtomicSimpleCPU::TickEvent::process()
{
cpu->tick();
}
const char *
AtomicSimpleCPU::TickEvent::description() const
{
return "AtomicSimpleCPU tick";
}
void
AtomicSimpleCPU::init()
{
@@ -94,7 +76,10 @@ AtomicSimpleCPU::init()
}
AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
: BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false),
: BaseSimpleCPU(p),
tickEvent([this]{ tick(); }, "AtomicSimpleCPU tick",
false, Event::CPU_Tick_Pri),
width(p->width), locked(false),
simulate_data_stalls(p->simulate_data_stalls),
simulate_inst_stalls(p->simulate_inst_stalls),
icachePort(name() + ".icache_port", this),

View File

@@ -60,16 +60,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
private:
struct TickEvent : public Event
{
AtomicSimpleCPU *cpu;
TickEvent(AtomicSimpleCPU *c);
void process();
const char *description() const;
};
TickEvent tickEvent;
EventFunctionWrapper tickEvent;
const int width;
bool locked;