sim: Move guts of quiesce and quiesceTick from ThreadContext to System.
authorGabe Black <gabeblack@google.com>
Thu, 6 Feb 2020 05:14:13 +0000 (21:14 -0800)
committerGabe Black <gabeblack@google.com>
Wed, 24 Jun 2020 01:25:25 +0000 (01:25 +0000)
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.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/cpu/thread_context.cc
src/sim/system.cc
src/sim/system.hh

index 83ed552309b1c7ac912b777acf0376e7a40146b8..5c194dff0cb9469ec768f91bec99ec747e1c18ba 100644 (file)
@@ -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);
 }
index 2bd781566dba6cde3766a34cd83a7920375cedf1..413341274551ba53f3716d6e511db327c441f440 100644 (file)
@@ -72,6 +72,32 @@ using namespace TheISA;
 
 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 @@ 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");
 }
index 192f9f4194b37f381a2204e90b0083eb4d89a07b..72734f86d5d8bc8d5151d7b912fa7ea10cf9199a 100644 (file)
@@ -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<Thread> 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()); }