From: Gabe Black Date: Thu, 6 Feb 2020 05:14:13 +0000 (-0800) Subject: sim: Move guts of quiesce and quiesceTick from ThreadContext to System. X-Git-Tag: v20.1.0.0~540 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=634c2963f5f3bb2bf1a252a9d1f62583186b9143;p=gem5.git sim: Move guts of quiesce and quiesceTick from ThreadContext to System. The functions in ThreadContext are now just convenience wrappers. Change-Id: Ib56c4bdd27e611fb667a8056dfae37065f4034eb Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25145 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc index 83ed55230..5c194dff0 100644 --- a/src/cpu/thread_context.cc +++ b/src/cpu/thread_context.cc @@ -129,30 +129,14 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two) void ThreadContext::quiesce() { - DPRINTF(Quiesce, "%s: quiesce()\n", getCpuPtr()->name()); - - suspend(); - auto *workload = getSystemPtr()->workload; - if (workload) - workload->recordQuiesce(); + getSystemPtr()->threads.quiesce(contextId()); } void ThreadContext::quiesceTick(Tick resume) { - BaseCPU *cpu = getCpuPtr(); - - EndQuiesceEvent *quiesceEvent = getQuiesceEvent(); - - cpu->reschedule(quiesceEvent, resume, true); - - DPRINTF(Quiesce, "%s: quiesceTick until %lu\n", cpu->name(), resume); - - suspend(); - auto *workload = getSystemPtr()->workload; - if (workload) - workload->recordQuiesce(); + getSystemPtr()->threads.quiesceTick(contextId(), resume); } void @@ -249,26 +233,8 @@ takeOverFrom(ThreadContext &ntc, ThreadContext &otc) ntc.setContextId(otc.contextId()); ntc.setThreadId(otc.threadId()); - if (FullSystem) { + 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); } diff --git a/src/sim/system.cc b/src/sim/system.cc index 2bd781566..413341274 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -72,6 +72,32 @@ using namespace TheISA; vector System::systemList; +void +System::Threads::Thread::resume() +{ +# if THE_ISA != NULL_ISA + DPRINTFS(Quiesce, context->getCpuPtr(), "activating\n"); + context->activate(); +# endif +} + +std::string +System::Threads::Thread::name() const +{ + assert(context); + return csprintf("%s.threads[%d]", context->getSystemPtr()->name(), + context->contextId()); +} + +void +System::Threads::Thread::quiesce() const +{ + context->suspend(); + auto *workload = context->getSystemPtr()->workload; + if (workload) + workload->recordQuiesce(); +} + ContextID System::Threads::insert(ThreadContext *tc, ContextID id) { @@ -88,12 +114,18 @@ System::Threads::insert(ThreadContext *tc, ContextID id) fatal_if(threads[id].context, "Cannot have two thread contexts with the same id (%d).", id); + auto *sys = tc->getSystemPtr(); + auto &t = thread(id); t.context = tc; + // Look up this thread again on resume, in case the threads vector has + // been reallocated. + t.resumeEvent = new EventFunctionWrapper( + [this, id](){ thread(id).resume(); }, sys->name()); # if THE_ISA != NULL_ISA int port = getRemoteGDBPort(); if (port) { - t.gdb = new RemoteGDB(tc->getSystemPtr(), tc, port + id); + t.gdb = new RemoteGDB(sys, tc, port + id); t.gdb->listen(); } # endif @@ -105,9 +137,17 @@ void System::Threads::replace(ThreadContext *tc, ContextID id) { auto &t = thread(id); - t.context = tc; + panic_if(!t.context, "Can't replace a context which doesn't exist."); if (t.gdb) t.gdb->replaceThreadContext(tc); +# if THE_ISA != NULL_ISA + if (t.resumeEvent->scheduled()) { + Tick when = t.resumeEvent->when(); + t.context->getCpuPtr()->deschedule(t.resumeEvent); + tc->getCpuPtr()->schedule(t.resumeEvent, when); + } +# endif + t.context = tc; } ThreadContext * @@ -134,6 +174,31 @@ System::Threads::numRunning() const return count; } +void +System::Threads::quiesce(ContextID id) +{ + auto &t = thread(id); +# if THE_ISA != NULL_ISA + BaseCPU *cpu = t.context->getCpuPtr(); + DPRINTFS(Quiesce, cpu, "quiesce()\n"); +# endif + t.quiesce(); +} + +void +System::Threads::quiesceTick(ContextID id, Tick when) +{ +# if THE_ISA != NULL_ISA + auto &t = thread(id); + BaseCPU *cpu = t.context->getCpuPtr(); + + DPRINTFS(Quiesce, cpu, "quiesceTick until %u\n", when); + t.quiesce(); + + cpu->reschedule(t.resumeEvent, when, true); +# endif +} + int System::numSystemsRunning = 0; System::System(Params *p) @@ -363,6 +428,14 @@ System::serialize(CheckpointOut &cp) const { SERIALIZE_SCALAR(pagePtr); + for (auto &t: threads.threads) { + Tick when = 0; + if (t.resumeEvent && t.resumeEvent->scheduled()) + when = t.resumeEvent->when(); + ContextID id = t.context->contextId(); + paramOut(cp, csprintf("quiesceEndTick_%d", id), when); + } + // also serialize the memories in the system physmem.serializeSection(cp, "physmem"); } @@ -373,6 +446,18 @@ System::unserialize(CheckpointIn &cp) { UNSERIALIZE_SCALAR(pagePtr); + for (auto &t: threads.threads) { + Tick when; + ContextID id = t.context->contextId(); + if (!optParamIn(cp, csprintf("quiesceEndTick_%d", id), when) || + !when || !t.resumeEvent) { + continue; + } +# if THE_ISA != NULL_ISA + t.context->getCpuPtr()->schedule(t.resumeEvent, when); +# endif + } + // also unserialize the memories in the system physmem.unserializeSection(cp, "physmem"); } diff --git a/src/sim/system.hh b/src/sim/system.hh index 192f9f419..72734f86d 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -108,6 +108,11 @@ class System : public SimObject, public PCEventScope ThreadContext *context = nullptr; bool active = false; BaseRemoteGDB *gdb = nullptr; + Event *resumeEvent = nullptr; + + void resume(); + std::string name() const; + void quiesce() const; }; std::vector threads; @@ -207,7 +212,8 @@ class System : public SimObject, public PCEventScope return count; } - void resume(ContextID id, Tick when); + void quiesce(ContextID id); + void quiesceTick(ContextID id, Tick when); const_iterator begin() const { return const_iterator(*this, 0); } const_iterator end() const { return const_iterator(*this, size()); }