void
InOrderThreadContext::takeOverFrom(ThreadContext *old_context)
{
- // some things should already be set up
- assert(getSystemPtr() == old_context->getSystemPtr());
- assert(getProcessPtr() == old_context->getProcessPtr());
-
- // copy over functional state
- setStatus(old_context->status());
- copyArchRegs(old_context);
+ ::takeOverFrom(*this, *old_context);
thread->funcExeInst = old_context->readFuncExeInst();
- old_context->setStatus(ThreadContext::Halted);
-
thread->noSquashFromTC = false;
thread->trapPending = false;
}
void
O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
{
- // some things should already be set up
- assert(getSystemPtr() == old_context->getSystemPtr());
- assert(getProcessPtr() == old_context->getProcessPtr());
+ ::takeOverFrom(*this, *old_context);
- // copy over functional state
- setStatus(old_context->status());
- copyArchRegs(old_context);
- setContextId(old_context->contextId());
- setThreadId(old_context->threadId());
-
- if (FullSystem) {
- EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent();
- if (other_quiesce) {
- // Point the quiesce event's TC at this TC so that it wakes up
- // the proper CPU.
- other_quiesce->tc = this;
- }
- if (thread->quiesceEvent) {
- thread->quiesceEvent->tc = this;
- }
-
- // Transfer kernel stats from one CPU to the other.
- thread->kernelStats = old_context->getKernelStats();
- } else {
- thread->funcExeInst = old_context->readFuncExeInst();
- }
-
- old_context->setStatus(ThreadContext::Halted);
+ thread->kernelStats = old_context->getKernelStats();
+ thread->funcExeInst = old_context->readFuncExeInst();
thread->noSquashFromTC = false;
thread->trapPending = false;
void
SimpleThread::takeOverFrom(ThreadContext *oldContext)
{
- // some things should already be set up
- if (FullSystem)
- assert(system == oldContext->getSystemPtr());
- assert(process == oldContext->getProcessPtr());
-
- copyState(oldContext);
- if (FullSystem) {
- EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
- if (quiesce) {
- // Point the quiesce event's TC at this TC so that it wakes up
- // the proper CPU.
- quiesce->tc = tc;
- }
- if (quiesceEvent) {
- quiesceEvent->tc = tc;
- }
-
- TheISA::Kernel::Statistics *stats = oldContext->getKernelStats();
- if (stats) {
- kernelStats = stats;
- }
- }
+ ::takeOverFrom(*tc, *oldContext);
+ kernelStats = oldContext->getKernelStats();
+ funcExeInst = oldContext->readFuncExeInst();
storeCondFailures = 0;
-
- oldContext->setStatus(ThreadContext::Halted);
-}
-
-void
-SimpleThread::copyTC(ThreadContext *context)
-{
- copyState(context);
-
- if (FullSystem) {
- EndQuiesceEvent *quiesce = context->getQuiesceEvent();
- if (quiesce) {
- quiesceEvent = quiesce;
- }
- TheISA::Kernel::Statistics *stats = context->getKernelStats();
- if (stats) {
- kernelStats = stats;
- }
- }
}
void
void regStats(const std::string &name);
- void copyTC(ThreadContext *context);
-
void copyState(ThreadContext *oldContext);
void serialize(std::ostream &os);
#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)
// 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);
+}
/** @} */
+
+/**
+ * Copy state between thread contexts in preparation for CPU handover.
+ *
+ * @note This method modifies the old thread contexts as well as the
+ * new thread context. The old thread context will have its quiesce
+ * event descheduled if it is scheduled and its status set to halted.
+ *
+ * @param new_tc Destination ThreadContext.
+ * @param old_tc Source ThreadContext.
+ */
+void takeOverFrom(ThreadContext &new_tc, ThreadContext &old_tc);
+
#endif