Gabe Black has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/25145 )
Change subject: sim: Move guts of quiesce and quiesceTick from
ThreadContext to System.
......................................................................
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 <power...@gmail.com>
Maintainer: Jason Lowe-Power <power...@gmail.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
M src/cpu/thread_context.cc
M src/sim/system.cc
M src/sim/system.hh
3 files changed, 97 insertions(+), 40 deletions(-)
Approvals:
Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved
kokoro: Regressions pass
diff --git a/src/cpu/thread_context.cc b/src/cpu/thread_context.cc
index 83ed552..5c194df 100644
--- a/src/cpu/thread_context.cc
+++ b/src/cpu/thread_context.cc
@@ -129,30 +129,14 @@
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 @@
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 2bd7815..4133412 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -72,6 +72,32 @@
vector<System *> 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 @@
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 @@
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 @@
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 @@
{
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 @@
{
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 192f9f4..72734f8 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -108,6 +108,11 @@
ThreadContext *context = nullptr;
bool active = false;
BaseRemoteGDB *gdb = nullptr;
+ Event *resumeEvent = nullptr;
+
+ void resume();
+ std::string name() const;
+ void quiesce() const;
};
std::vector<Thread> threads;
@@ -207,7 +212,8 @@
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());
}
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/25145
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ib56c4bdd27e611fb667a8056dfae37065f4034eb
Gerrit-Change-Number: 25145
Gerrit-PatchSet: 42
Gerrit-Owner: Gabe Black <gabebl...@google.com>
Gerrit-Reviewer: Andreas Sandberg <andreas.sandb...@arm.com>
Gerrit-Reviewer: Anthony Gutierrez <anthony.gutier...@amd.com>
Gerrit-Reviewer: Bobby R. Bruce <bbr...@ucdavis.edu>
Gerrit-Reviewer: Brandon Potter <brandon.pot...@amd.com>
Gerrit-Reviewer: Gabe Black <gabebl...@google.com>
Gerrit-Reviewer: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: Jason Lowe-Power <power...@gmail.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s