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);
o3_tc->thread = this->thread[tid];
if (FullSystem) {
// Setup quiesce event.
this->thread[tid]->quiesceEvent = new EndQuiesceEvent(tc);
}
// Give the thread the TC.
this->thread[tid]->tc = tc;

View file

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

View file

@ -41,6 +41,7 @@
* Authors: Kevin Lim
*/
#include "arch/kernel_stats.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
@ -48,6 +49,8 @@
#include "cpu/quiesce_event.hh"
#include "cpu/thread_context.hh"
#include "debug/Context.hh"
#include "debug/Quiesce.hh"
#include "params/BaseCPU.hh"
#include "sim/full_system.hh"
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
serialize(ThreadContext &tc, CheckpointOut &cp)
{

View file

@ -174,6 +174,12 @@ class ThreadContext
/// Set the status to Halted.
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 takeOverFrom(ThreadContext *old_context) = 0;
@ -367,6 +373,12 @@ class ProxyThreadContext : public ThreadContext
/// Set the status to Halted.
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 takeOverFrom(ThreadContext *oldContext)

View file

@ -234,105 +234,34 @@ void
quiesce(ThreadContext *tc)
{
DPRINTF(PseudoInst, "PseudoInst::quiesce()\n");
if (!FullSystem)
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();
tc->quiesce();
}
void
quiesceSkip(ThreadContext *tc)
{
DPRINTF(PseudoInst, "PseudoInst::quiesceSkip()\n");
if (!FullSystem)
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();
tc->quiesceTick(tc->getCpuPtr()->nextCycle() + 1);
}
void
quiesceNs(ThreadContext *tc, uint64_t ns)
{
DPRINTF(PseudoInst, "PseudoInst::quiesceNs(%i)\n", ns);
if (!FullSystem)
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();
tc->quiesceTick(curTick() + SimClock::Int::ns * ns);
}
void
quiesceCycles(ThreadContext *tc, uint64_t cycles)
{
DPRINTF(PseudoInst, "PseudoInst::quiesceCycles(%i)\n", cycles);
if (!FullSystem)
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();
tc->quiesceTick(tc->getCpuPtr()->clockEdge(Cycles(cycles)));
}
uint64_t
quiesceTime(ThreadContext *tc)
{
DPRINTF(PseudoInst, "PseudoInst::quiesceTime()\n");
if (!FullSystem) {
panicFsOnlyPseudoInst("quiesceTime");
return 0;
}
return (tc->readLastActivate() - tc->readLastSuspend()) /
SimClock::Int::ns;