sim: Refactor quiesce and remove FS asserts

The quiesce family of magic ops can be simplified by the inclusion of
quiesceTick() and quiesce() functions on ThreadContext.  This patch also
gets rid of the FS guards, since suspending a CPU is also a valid
operation for SE mode.
This commit is contained in:
Michael LeBeane 2016-09-13 23:17:42 -04:00
parent 2068af5768
commit 458d4a3c7b
5 changed files with 56 additions and 79 deletions

View file

@ -380,10 +380,9 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
assert(o3_tc->cpu); assert(o3_tc->cpu);
o3_tc->thread = this->thread[tid]; o3_tc->thread = this->thread[tid];
if (FullSystem) { // Setup quiesce event.
// Setup quiesce event. this->thread[tid]->quiesceEvent = new EndQuiesceEvent(tc);
this->thread[tid]->quiesceEvent = new EndQuiesceEvent(tc);
}
// Give the thread the TC. // Give the thread the TC.
this->thread[tid]->tc = tc; this->thread[tid]->tc = tc;

View file

@ -69,6 +69,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
{ {
clearArchRegs(); clearArchRegs();
tc = new ProxyThreadContext<SimpleThread>(this); tc = new ProxyThreadContext<SimpleThread>(this);
quiesceEvent = new EndQuiesceEvent(tc);
} }
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,

View file

@ -41,6 +41,7 @@
* Authors: Kevin Lim * Authors: Kevin Lim
*/ */
#include "arch/kernel_stats.hh"
#include "base/misc.hh" #include "base/misc.hh"
#include "base/trace.hh" #include "base/trace.hh"
#include "config/the_isa.hh" #include "config/the_isa.hh"
@ -48,6 +49,8 @@
#include "cpu/quiesce_event.hh" #include "cpu/quiesce_event.hh"
#include "cpu/thread_context.hh" #include "cpu/thread_context.hh"
#include "debug/Context.hh" #include "debug/Context.hh"
#include "debug/Quiesce.hh"
#include "params/BaseCPU.hh"
#include "sim/full_system.hh" #include "sim/full_system.hh"
void void
@ -103,6 +106,39 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
} }
void
ThreadContext::quiesce()
{
if (!getCpuPtr()->params()->do_quiesce)
return;
DPRINTF(Quiesce, "%s: quiesce()\n", getCpuPtr()->name());
suspend();
if (getKernelStats())
getKernelStats()->quiesce();
}
void
ThreadContext::quiesceTick(Tick resume)
{
BaseCPU *cpu = getCpuPtr();
if (!cpu->params()->do_quiesce)
return;
EndQuiesceEvent *quiesceEvent = getQuiesceEvent();
cpu->reschedule(quiesceEvent, resume, true);
DPRINTF(Quiesce, "%s: quiesceTick until %lu\n", cpu->name(), resume);
suspend();
if (getKernelStats())
getKernelStats()->quiesce();
}
void void
serialize(ThreadContext &tc, CheckpointOut &cp) serialize(ThreadContext &tc, CheckpointOut &cp)
{ {

View file

@ -174,6 +174,12 @@ class ThreadContext
/// Set the status to Halted. /// Set the status to Halted.
virtual void halt() = 0; virtual void halt() = 0;
/// Quiesce thread context
void quiesce();
/// Quiesce, suspend, and schedule activate at resume
void quiesceTick(Tick resume);
virtual void dumpFuncProfile() = 0; virtual void dumpFuncProfile() = 0;
virtual void takeOverFrom(ThreadContext *old_context) = 0; virtual void takeOverFrom(ThreadContext *old_context) = 0;
@ -367,6 +373,12 @@ class ProxyThreadContext : public ThreadContext
/// Set the status to Halted. /// Set the status to Halted.
void halt() { actualTC->halt(); } void halt() { actualTC->halt(); }
/// Quiesce thread context
void quiesce() { actualTC->quiesce(); }
/// Quiesce, suspend, and schedule activate at resume
void quiesceTick(Tick resume) { actualTC->quiesceTick(resume); }
void dumpFuncProfile() { actualTC->dumpFuncProfile(); } void dumpFuncProfile() { actualTC->dumpFuncProfile(); }
void takeOverFrom(ThreadContext *oldContext) void takeOverFrom(ThreadContext *oldContext)

View file

@ -234,105 +234,34 @@ void
quiesce(ThreadContext *tc) quiesce(ThreadContext *tc)
{ {
DPRINTF(PseudoInst, "PseudoInst::quiesce()\n"); DPRINTF(PseudoInst, "PseudoInst::quiesce()\n");
if (!FullSystem) tc->quiesce();
panicFsOnlyPseudoInst("quiesce");
if (!tc->getCpuPtr()->params()->do_quiesce)
return;
DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
tc->suspend();
if (tc->getKernelStats())
tc->getKernelStats()->quiesce();
} }
void void
quiesceSkip(ThreadContext *tc) quiesceSkip(ThreadContext *tc)
{ {
DPRINTF(PseudoInst, "PseudoInst::quiesceSkip()\n"); DPRINTF(PseudoInst, "PseudoInst::quiesceSkip()\n");
if (!FullSystem) tc->quiesceTick(tc->getCpuPtr()->nextCycle() + 1);
panicFsOnlyPseudoInst("quiesceSkip");
BaseCPU *cpu = tc->getCpuPtr();
if (!cpu->params()->do_quiesce)
return;
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
Tick resume = cpu->nextCycle() + 1;
cpu->reschedule(quiesceEvent, resume, true);
DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n",
cpu->name(), resume);
tc->suspend();
if (tc->getKernelStats())
tc->getKernelStats()->quiesce();
} }
void void
quiesceNs(ThreadContext *tc, uint64_t ns) quiesceNs(ThreadContext *tc, uint64_t ns)
{ {
DPRINTF(PseudoInst, "PseudoInst::quiesceNs(%i)\n", ns); DPRINTF(PseudoInst, "PseudoInst::quiesceNs(%i)\n", ns);
if (!FullSystem) tc->quiesceTick(curTick() + SimClock::Int::ns * ns);
panicFsOnlyPseudoInst("quiesceNs");
BaseCPU *cpu = tc->getCpuPtr();
if (!cpu->params()->do_quiesce)
return;
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
Tick resume = curTick() + SimClock::Int::ns * ns;
cpu->reschedule(quiesceEvent, resume, true);
DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
cpu->name(), ns, resume);
tc->suspend();
if (tc->getKernelStats())
tc->getKernelStats()->quiesce();
} }
void void
quiesceCycles(ThreadContext *tc, uint64_t cycles) quiesceCycles(ThreadContext *tc, uint64_t cycles)
{ {
DPRINTF(PseudoInst, "PseudoInst::quiesceCycles(%i)\n", cycles); DPRINTF(PseudoInst, "PseudoInst::quiesceCycles(%i)\n", cycles);
if (!FullSystem) tc->quiesceTick(tc->getCpuPtr()->clockEdge(Cycles(cycles)));
panicFsOnlyPseudoInst("quiesceCycles");
BaseCPU *cpu = tc->getCpuPtr();
if (!cpu->params()->do_quiesce)
return;
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
Tick resume = cpu->clockEdge(Cycles(cycles));
cpu->reschedule(quiesceEvent, resume, true);
DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
cpu->name(), cycles, resume);
tc->suspend();
if (tc->getKernelStats())
tc->getKernelStats()->quiesce();
} }
uint64_t uint64_t
quiesceTime(ThreadContext *tc) quiesceTime(ThreadContext *tc)
{ {
DPRINTF(PseudoInst, "PseudoInst::quiesceTime()\n"); DPRINTF(PseudoInst, "PseudoInst::quiesceTime()\n");
if (!FullSystem) {
panicFsOnlyPseudoInst("quiesceTime");
return 0;
}
return (tc->readLastActivate() - tc->readLastSuspend()) / return (tc->readLastActivate() - tc->readLastSuspend()) /
SimClock::Int::ns; SimClock::Int::ns;