cpu,sim: Delegate PCEvent scheduling from Systems to ThreadContexts.

The System keeps track of what events are live so new ThreadContexts
can have the same set of events as the other ThreadContexts.

Change-Id: Id22bfa0af7592a43d97be1564ca067b08ac1de7c
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22106
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 81bf4c1..9e4bdcd 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -412,7 +412,6 @@
             int count = 0;
             do {
                 oldpc = thread->instAddr();
-                system->pcEventQueue.service(oldpc, tc);
                 thread->pcEventQueue.service(oldpc, tc);
                 count++;
             } while (oldpc != thread->instAddr());
diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc
index 5bf3120..24506fc 100644
--- a/src/cpu/minor/execute.cc
+++ b/src/cpu/minor/execute.cc
@@ -841,7 +841,6 @@
     Addr oldPC;
     do {
         oldPC = thread->instAddr();
-        cpu.system->pcEventQueue.service(oldPC, thread);
         cpu.threads[thread_id]->pcEventQueue.service(oldPC, thread);
         num_pc_event_checks++;
     } while (oldPC != thread->instAddr());
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 23f10fe..fa2d724 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -1112,8 +1112,6 @@
                            !thread[tid]->trapPending);
                     do {
                         oldpc = pc[tid].instAddr();
-                        cpu->system->pcEventQueue.service(
-                                oldpc, thread[tid]->getTC());
                         thread[tid]->pcEventQueue.service(
                                 oldpc, thread[tid]->getTC());
                         count++;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 8cecf70..248494b 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -144,7 +144,6 @@
     Addr oldpc, pc = threadInfo[curThread]->thread->instAddr();
     do {
         oldpc = pc;
-        system->pcEventQueue.service(oldpc, threadContexts[curThread]);
         threadInfo[curThread]->thread->pcEventQueue.service(
                 oldpc, threadContexts[curThread]);
         pc = threadInfo[curThread]->thread->instAddr();
diff --git a/src/sim/system.cc b/src/sim/system.cc
index e993a73..f2bbd8c 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -265,6 +265,8 @@
              "Cannot have two CPUs with the same id (%d)\n", id);
 
     threadContexts[id] = tc;
+    for (auto *e: liveEvents)
+        tc->schedule(e);
 
 #if THE_ISA != NULL_ISA
     int port = getRemoteGDBPort();
@@ -295,13 +297,21 @@
 bool
 System::schedule(PCEvent *event)
 {
-    return pcEventQueue.schedule(event);
+    bool all = true;
+    liveEvents.push_back(event);
+    for (auto *tc: threadContexts)
+        all = tc->schedule(event) && all;
+    return all;
 }
 
 bool
 System::remove(PCEvent *event)
 {
-    return pcEventQueue.remove(event);
+    bool all = true;
+    liveEvents.remove(event);
+    for (auto *tc: threadContexts)
+        all = tc->remove(event) && all;
+    return all;
 }
 
 int
@@ -363,6 +373,10 @@
               context_id, threadContexts.size());
     }
 
+    for (auto *e: liveEvents) {
+        threadContexts[context_id]->remove(e);
+        tc->schedule(e);
+    }
     threadContexts[context_id] = tc;
     if (context_id < remoteGDB.size())
         remoteGDB[context_id]->replaceThreadContext(tc);
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 8c06603..d205ffb 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -99,6 +99,7 @@
         { panic("SystemPort does not expect retry!\n"); }
     };
 
+    std::list<PCEvent *> liveEvents;
     SystemPort _systemPort;
 
   public:
@@ -186,8 +187,6 @@
      */
     unsigned int cacheLineSize() const { return _cacheLineSize; }
 
-    PCEventQueue pcEventQueue;
-
     std::vector<ThreadContext *> threadContexts;
     const bool multiThread;