syscall_emul: [patch 13/22] add system call retry capability
[gem5.git] / src / cpu / o3 / commit_impl.hh
index 403e582d3985f14770e87743826c47dda1f0a30d..ea77f18fb54613c916130c09c55284f70aec3aba 100644 (file)
@@ -173,6 +173,7 @@ DefaultCommit<Impl>::regProbePoints()
 {
     ppCommit = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Commit");
     ppCommitStall = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "CommitStall");
+    ppSquash = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Squash");
 }
 
 template <class Impl>
@@ -184,19 +185,18 @@ DefaultCommit<Impl>::regStats()
         .name(name() + ".commitSquashedInsts")
         .desc("The number of squashed insts skipped by commit")
         .prereq(commitSquashedInsts);
-    commitSquashEvents
-        .name(name() + ".commitSquashEvents")
-        .desc("The number of times commit is told to squash")
-        .prereq(commitSquashEvents);
+
     commitNonSpecStalls
         .name(name() + ".commitNonSpecStalls")
         .desc("The number of times commit has been forced to stall to "
               "communicate backwards")
         .prereq(commitNonSpecStalls);
+
     branchMispredicts
         .name(name() + ".branchMispredicts")
         .desc("The number of times a branch was mispredicted")
         .prereq(branchMispredicts);
+
     numCommittedDist
         .init(0,commitWidth,1)
         .name(name() + ".committed_per_cycle")
@@ -282,13 +282,6 @@ DefaultCommit<Impl>::regStats()
         ;
     statCommittedInstType.ysubnames(Enums::OpClassStrings);
 
-    commitEligible
-        .init(cpu->numThreads)
-        .name(name() + ".bw_limited")
-        .desc("number of insts not committed due to BW limits")
-        .flags(total)
-        ;
-
     commitEligibleSamples
         .name(name() + ".bw_lim_events")
         .desc("number cycles where commit BW limit reached")
@@ -533,13 +526,16 @@ DefaultCommit<Impl>::numROBFreeEntries(ThreadID tid)
 
 template <class Impl>
 void
-DefaultCommit<Impl>::generateTrapEvent(ThreadID tid)
+DefaultCommit<Impl>::generateTrapEvent(ThreadID tid, Fault inst_fault)
 {
     DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
 
     TrapEvent *trap = new TrapEvent(this, tid);
 
-    cpu->schedule(trap, cpu->clockEdge(trapLatency));
+    Cycles latency = dynamic_pointer_cast<SyscallRetryFault>(inst_fault) ?
+                     cpu->syscallRetryLatency : trapLatency;
+
+    cpu->schedule(trap, cpu->clockEdge(latency));
     trapInFlight[tid] = true;
     thread[tid]->trapPending = true;
 }
@@ -774,10 +770,11 @@ DefaultCommit<Impl>::handleInterrupt()
 
         commitStatus[0] = TrapPending;
 
+        interrupt = NoFault;
+
         // Generate trap squash event.
-        generateTrapEvent(0);
+        generateTrapEvent(0, interrupt);
 
-        interrupt = NoFault;
         avoidQuiesceLiveLock = false;
     } else {
         DPRINTF(Commit, "Interrupt pending: instruction is %sin "
@@ -906,13 +903,10 @@ DefaultCommit<Impl>::commit()
                 if (toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) {
                      toIEW->commitInfo[tid].branchTaken = true;
                 }
+                ++branchMispredicts;
             }
 
             toIEW->commitInfo[tid].pc = fromIEW->pc[tid];
-
-            if (toIEW->commitInfo[tid].mispredictInst) {
-                ++branchMispredicts;
-            }
         }
 
         if (commitStatus[tid] == ROBSquashing) {
@@ -997,7 +991,7 @@ DefaultCommit<Impl>::commitInsts()
         if (interrupt != NoFault)
             handleInterrupt();
 
-        int commit_thread = getCommittingThread();
+        ThreadID commit_thread = getCommittingThread();
 
         if (commit_thread == -1 || !rob->isHeadReady(commit_thread))
             break;
@@ -1021,6 +1015,8 @@ DefaultCommit<Impl>::commitInsts()
             rob->retireHead(commit_thread);
 
             ++commitSquashedInsts;
+            // Notify potential listeners that this instruction is squashed
+            ppSquash->notify(head_inst);
 
             // Record that the number of ROB entries has changed.
             changedROBNumEntries[tid] = true;
@@ -1156,7 +1152,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
         // think are possible.
         assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
                || head_inst->isMemBarrier() || head_inst->isWriteBarrier() ||
-               (head_inst->isLoad() && head_inst->uncacheable()));
+               (head_inst->isLoad() && head_inst->strictlyOrdered()));
 
         DPRINTF(Commit, "Encountered a barrier or non-speculative "
                 "instruction [sn:%lli] at the head of the ROB, PC %s.\n",
@@ -1173,11 +1169,11 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
         // it is executed.
         head_inst->clearCanCommit();
 
-        if (head_inst->isLoad() && head_inst->uncacheable()) {
-            DPRINTF(Commit, "[sn:%lli]: Uncached load, PC %s.\n",
+        if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
+            DPRINTF(Commit, "[sn:%lli]: Strictly ordered load, PC %s.\n",
                     head_inst->seqNum, head_inst->pcState());
-            toIEW->commitInfo[tid].uncached = true;
-            toIEW->commitInfo[tid].uncachedLoad = head_inst;
+            toIEW->commitInfo[tid].strictlyOrdered = true;
+            toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
         } else {
             ++commitNonSpecStalls;
         }
@@ -1248,7 +1244,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
         }
 
         // Generate trap squash event.
-        generateTrapEvent(tid);
+        generateTrapEvent(tid, inst_fault);
         return false;
     }
 
@@ -1349,10 +1345,8 @@ DefaultCommit<Impl>::markCompletedInsts()
 {
     // Grab completed insts out of the IEW instruction queue, and mark
     // instructions completed within the ROB.
-    for (int inst_num = 0;
-         inst_num < fromIEW->size && fromIEW->insts[inst_num];
-         ++inst_num)
-    {
+    for (int inst_num = 0; inst_num < fromIEW->size; ++inst_num) {
+        assert(fromIEW->insts[inst_num]);
         if (!fromIEW->insts[inst_num]->isSquashed()) {
             DPRINTF(Commit, "[tid:%i]: Marking PC %s, [sn:%lli] ready "
                     "within ROB.\n",