cpu: Fix broken thread context handover

The thread context handover code used to break when multiple handovers
were performed during the same quiesce period. Previously, the thread
contexts would assign the TC pointer in the old quiesce event to the
new TC. This obviously broke in cases where multiple switches were
performed within the same quiesce period, in which case the TC pointer
in the quiesce event would point to an old CPU.

The new implementation deschedules pending quiesce events in the old
TC and schedules a new quiesce event in the new TC. The code has been
refactored to remove most of the code duplication.
This commit is contained in:
Andreas Sandberg
2013-01-07 13:05:46 -05:00
parent fca4fea769
commit 52ff37caa3
6 changed files with 57 additions and 79 deletions

View File

@@ -43,8 +43,11 @@
#include "base/misc.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/base.hh"
#include "cpu/quiesce_event.hh"
#include "cpu/thread_context.hh"
#include "debug/Context.hh"
#include "sim/full_system.hh"
void
ThreadContext::compare(ThreadContext *one, ThreadContext *two)
@@ -136,3 +139,37 @@ unserialize(ThreadContext &tc, Checkpoint *cp, const std::string &section)
// thread_num and cpu_id are deterministic from the config
}
void
takeOverFrom(ThreadContext &ntc, ThreadContext &otc)
{
assert(ntc.getProcessPtr() == otc.getProcessPtr());
ntc.setStatus(otc.status());
ntc.copyArchRegs(&otc);
ntc.setContextId(otc.contextId());
ntc.setThreadId(otc.threadId());
if (FullSystem) {
assert(ntc.getSystemPtr() == otc.getSystemPtr());
BaseCPU *ncpu(ntc.getCpuPtr());
assert(ncpu);
EndQuiesceEvent *oqe(otc.getQuiesceEvent());
assert(oqe);
assert(oqe->tc == &otc);
BaseCPU *ocpu(otc.getCpuPtr());
assert(ocpu);
EndQuiesceEvent *nqe(ntc.getQuiesceEvent());
assert(nqe);
assert(nqe->tc == &ntc);
if (oqe->scheduled()) {
ncpu->schedule(nqe, oqe->when());
ocpu->deschedule(oqe);
}
}
otc.setStatus(ThreadContext::Halted);
}