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:
parent
2068af5768
commit
458d4a3c7b
5 changed files with 56 additions and 79 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue