cpu: fix how branching is handled when a thread is suspended in MinorCPU
authorTuan Ta <qtt2@cornell.edu>
Mon, 2 Apr 2018 20:22:16 +0000 (16:22 -0400)
committerTuan Ta <qtt2@cornell.edu>
Fri, 8 Feb 2019 15:25:30 +0000 (15:25 +0000)
When a thread is suspended, all instructions after the suspension need
to be discarded since the thread will take a different execution stream
when it wakes up.

To do that, in MinorCPU, whenever a thread gets suspended, we change the
current execution stream by updating the current branch with
BranchData::SuspendThread reason.

Change-Id: I7cdcda22c1cf6e8ac8db8800b7d9ec052433fdf3
Reviewed-on: https://gem5-review.googlesource.com/c/9626
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Giacomo Gabrielli <giacomo.gabrielli@gmail.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>

src/cpu/minor/execute.cc

index d7cb475c687ec2624f11c906f3221b798935d079..234a233c2ec6b73952a105be6c099feac0d37898 100644 (file)
@@ -248,7 +248,14 @@ Execute::tryToBranch(MinorDynInstPtr inst, Fault fault, BranchData &branch)
             pc_before, target);
     }
 
-    if (inst->predictedTaken && !force_branch) {
+    if (thread->status() == ThreadContext::Suspended) {
+        /* Thread got suspended */
+        DPRINTF(Branch, "Thread got suspended: branch from 0x%x to 0x%x "
+            "inst: %s\n",
+            inst->pc.instAddr(), target.instAddr(), *inst);
+
+        reason = BranchData::SuspendThread;
+    } else if (inst->predictedTaken && !force_branch) {
         /* Predicted to branch */
         if (!must_branch) {
             /* No branch was taken, change stream to get us back to the
@@ -1054,8 +1061,7 @@ Execute::commit(ThreadID thread_id, bool only_commit_microops, bool discard,
         !branch.isStreamChange() && /* No real branch */
         fault == NoFault && /* No faults */
         completed_inst && /* Still finding instructions to execute */
-        num_insts_committed != commitLimit && /* Not reached commit limit */
-        cpu.getContext(thread_id)->status() != ThreadContext::Suspended
+        num_insts_committed != commitLimit /* Not reached commit limit */
         )
     {
         if (only_commit_microops) {