Support for draining, and the new method of switching out. Now switching out happens...
authorKevin Lim <ktlim@umich.edu>
Thu, 6 Jul 2006 17:59:02 +0000 (13:59 -0400)
committerKevin Lim <ktlim@umich.edu>
Thu, 6 Jul 2006 17:59:02 +0000 (13:59 -0400)
src/cpu/o3/commit.hh:
src/cpu/o3/commit_impl.hh:
src/cpu/o3/cpu.cc:
src/cpu/o3/cpu.hh:
src/cpu/o3/decode.hh:
src/cpu/o3/decode_impl.hh:
src/cpu/o3/fetch.hh:
src/cpu/o3/fetch_impl.hh:
src/cpu/o3/iew.hh:
src/cpu/o3/iew_impl.hh:
src/cpu/o3/rename.hh:
src/cpu/o3/rename_impl.hh:
    Support for draining, new method of switching out.

--HG--
extra : convert_revision : 05bf8b271ec85b3e2c675c3bed6c42aeba21f465

12 files changed:
src/cpu/o3/commit.hh
src/cpu/o3/commit_impl.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/decode.hh
src/cpu/o3/decode_impl.hh
src/cpu/o3/fetch.hh
src/cpu/o3/fetch_impl.hh
src/cpu/o3/iew.hh
src/cpu/o3/iew_impl.hh
src/cpu/o3/rename.hh
src/cpu/o3/rename_impl.hh

index 60b555269ec6bc87e10fb9e31dd56df010756010..49ff5cdadbfd6620b7b16a896e21bd8556495812 100644 (file)
@@ -187,11 +187,14 @@ class DefaultCommit
     /** Initializes stage by sending back the number of free entries. */
     void initStage();
 
-    /** Initializes the switching out of commit. */
-    void switchOut();
+    /** Initializes the draining of commit. */
+    void drain();
+
+    /** Resumes execution after draining. */
+    void resume();
 
     /** Completes the switch out of commit. */
-    void doSwitchOut();
+    void switchOut();
 
     /** Takes over from another CPU's thread. */
     void takeOverFrom();
@@ -383,8 +386,8 @@ class DefaultCommit
     /** Number of Active Threads */
     unsigned numThreads;
 
-    /** Is a switch out pending. */
-    bool switchPending;
+    /** Is a drain pending. */
+    bool drainPending;
 
     /** Is commit switched out. */
     bool switchedOut;
index 06b8e8a954c53ac197d64f7730cc9c9325ece97e..2eb05afac2ac6168ffd73796039a2553f3ba7310 100644 (file)
@@ -80,7 +80,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
       renameWidth(params->renameWidth),
       commitWidth(params->commitWidth),
       numThreads(params->numberOfThreads),
-      switchPending(false),
+      drainPending(false),
       switchedOut(false),
       trapLatency(params->trapLatency),
       fetchTrapLatency(params->fetchTrapLatency)
@@ -351,20 +351,26 @@ DefaultCommit<Impl>::initStage()
 
 template <class Impl>
 void
-DefaultCommit<Impl>::switchOut()
+DefaultCommit<Impl>::drain()
 {
-    switchPending = true;
+    drainPending = true;
 }
 
 template <class Impl>
 void
-DefaultCommit<Impl>::doSwitchOut()
+DefaultCommit<Impl>::switchOut()
 {
     switchedOut = true;
-    switchPending = false;
+    drainPending = false;
     rob->switchOut();
 }
 
+template <class Impl>
+void
+DefaultCommit<Impl>::resume()
+{
+}
+
 template <class Impl>
 void
 DefaultCommit<Impl>::takeOverFrom()
@@ -557,8 +563,9 @@ DefaultCommit<Impl>::tick()
     wroteToTimeBuffer = false;
     _nextStatus = Inactive;
 
-    if (switchPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
-        cpu->signalSwitched();
+    if (drainPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
+        cpu->signalDrained();
+        drainPending = false;
         return;
     }
 
index fb7739db87620fc3eca305287ebc9c0d7cdbeb1b..5bda57cf8ac5d28a6ad715c6442ed2086df5d606 100644 (file)
@@ -158,7 +158,7 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
       physmem(system->physmem),
 #endif // FULL_SYSTEM
       mem(params->mem),
-      switchCount(0),
+      drainCount(0),
       deferRegistration(params->deferRegistration),
       numThreads(number_of_threads)
 {
@@ -713,45 +713,72 @@ FullO3CPU<Impl>::haltContext(int tid)
 }
 
 template <class Impl>
-void
-FullO3CPU<Impl>::switchOut()
+bool
+FullO3CPU<Impl>::drain(Event *drain_event)
 {
-    switchCount = 0;
-    fetch.switchOut();
-    decode.switchOut();
-    rename.switchOut();
-    iew.switchOut();
-    commit.switchOut();
+    drainCount = 0;
+    drainEvent = drain_event;
+    fetch.drain();
+    decode.drain();
+    rename.drain();
+    iew.drain();
+    commit.drain();
 
     // Wake the CPU and record activity so everything can drain out if
     // the CPU is currently idle.
     wakeCPU();
     activityRec.activity();
+
+    return false;
 }
 
 template <class Impl>
 void
-FullO3CPU<Impl>::signalSwitched()
-{
-    if (++switchCount == NumStages) {
-        fetch.doSwitchOut();
-        rename.doSwitchOut();
-        commit.doSwitchOut();
-        instList.clear();
-        while (!removeList.empty()) {
-            removeList.pop();
-        }
+FullO3CPU<Impl>::resume()
+{
+    if (_status == SwitchedOut)
+        return;
+    fetch.resume();
+    decode.resume();
+    rename.resume();
+    iew.resume();
+    commit.resume();
 
-#if USE_CHECKER
-        if (checker)
-            checker->switchOut();
-#endif
+    if (!tickEvent.scheduled())
+        tickEvent.schedule(curTick);
+    _status = Running;
+}
 
+template <class Impl>
+void
+FullO3CPU<Impl>::signalDrained()
+{
+    if (++drainCount == NumStages) {
         if (tickEvent.scheduled())
             tickEvent.squash();
-        _status = SwitchedOut;
+        _status = Drained;
+        drainEvent->process();
     }
-    assert(switchCount <= 5);
+    assert(drainCount <= 5);
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::switchOut()
+{
+    fetch.switchOut();
+    rename.switchOut();
+    commit.switchOut();
+    instList.clear();
+    while (!removeList.empty()) {
+        removeList.pop();
+    }
+
+    _status = SwitchedOut;
+#if USE_CHECKER
+    if (checker)
+        checker->switchOut();
+#endif
 }
 
 template <class Impl>
index bd045160192dcd04a7b3c0e3671a79ba5eb690a5..cf374760141615b57b4873435e581cdee500131a 100644 (file)
@@ -57,6 +57,8 @@ class Checker;
 class ThreadContext;
 template <class>
 class O3ThreadContext;
+
+class Checkpoint;
 class MemObject;
 class Process;
 
@@ -109,6 +111,7 @@ class FullO3CPU : public BaseO3CPU
         Idle,
         Halted,
         Blocked,
+        Drained,
         SwitchedOut
     };
 
@@ -270,14 +273,21 @@ class FullO3CPU : public BaseO3CPU
      */
     virtual void syscall(int tid) { panic("Unimplemented!"); }
 
-    /** Switches out this CPU. */
-    void switchOut();
+    /** Starts draining the CPU's pipeline of all instructions in
+     * order to stop all memory accesses. */
+    virtual bool drain(Event *drain_event);
+
+    /** Resumes execution after a drain. */
+    virtual void resume();
 
     /** Signals to this CPU that a stage has completed switching out. */
-    void signalSwitched();
+    void signalDrained();
+
+    /** Switches out this CPU. */
+    virtual void switchOut();
 
     /** Takes over from another CPU. */
-    void takeOverFrom(BaseCPU *oldCPU);
+    virtual void takeOverFrom(BaseCPU *oldCPU);
 
     /** Get the current instruction sequence number, and increment it. */
     InstSeqNum getAndIncrementInstSeq()
@@ -550,8 +560,11 @@ class FullO3CPU : public BaseO3CPU
     /** Pointer to memory. */
     MemObject *mem;
 
-    /** Counter of how many stages have completed switching out. */
-    int switchCount;
+    /** Event to call process() on once draining has completed. */
+    Event *drainEvent;
+
+    /** Counter of how many stages have completed draining. */
+    int drainCount;
 
     /** Pointers to all of the threads in the CPU. */
     std::vector<Thread *> thread;
index 1edf3335db74702ff84e6cfb179f1a3897efe12c..1e96f188485beab0be984c9bb3b298a18d9f74d8 100644 (file)
@@ -109,8 +109,14 @@ class DefaultDecode
     /** Sets pointer to list of active threads. */
     void setActiveThreads(std::list<unsigned> *at_ptr);
 
+    /** Drains the decode stage. */
+    void drain();
+
+    /** Resumes execution after a drain. */
+    void resume() { }
+
     /** Switches out the decode stage. */
-    void switchOut();
+    void switchOut() { }
 
     /** Takes over from another CPU's thread. */
     void takeOverFrom();
index 16be017845dad80184017c6f998ffaf5eb6e8ea6..71637883bc1e9d25b3cb884045531958545e2f31 100644 (file)
@@ -166,10 +166,10 @@ DefaultDecode<Impl>::setActiveThreads(list<unsigned> *at_ptr)
 
 template <class Impl>
 void
-DefaultDecode<Impl>::switchOut()
+DefaultDecode<Impl>::drain()
 {
-    // Decode can immediately switch out.
-    cpu->signalSwitched();
+    // Decode is done draining at any time.
+    cpu->signalDrained();
 }
 
 template <class Impl>
index 848ebf39e039d3c504469aed658ebad9b977137a..9611f0455b46a6974091df251f9a97b2efb80a7b 100644 (file)
@@ -180,11 +180,14 @@ class DefaultFetch
     /** Processes cache completion event. */
     void processCacheCompletion(PacketPtr pkt);
 
-    /** Begins the switch out of the fetch stage. */
-    void switchOut();
+    /** Begins the drain of the fetch stage. */
+    void drain();
+
+    /** Resumes execution after a drain. */
+    void resume();
 
-    /** Completes the switch out of the fetch stage. */
-    void doSwitchOut();
+    /** Tells fetch stage to prepare to be switched out. */
+    void switchOut();
 
     /** Takes over from another CPU's thread. */
     void takeOverFrom();
@@ -421,6 +424,9 @@ class DefaultFetch
      */
     bool interruptPending;
 
+    /** Is there a drain pending. */
+    bool drainPending;
+
     /** Records if fetch is switched out. */
     bool switchedOut;
 
index 60eb76d1784ba2e7f0a0e063b551b5888b486126..500b5304ebf77de9f3dbace83c136f50f8130d1a 100644 (file)
@@ -109,6 +109,7 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
       numThreads(params->numberOfThreads),
       numFetchingThreads(params->smtNumFetchingThreads),
       interruptPending(false),
+      drainPending(false),
       switchedOut(false)
 {
     if (numThreads > Impl::MaxThreads)
@@ -353,7 +354,8 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
     // to return.
     if (fetchStatus[tid] != IcacheWaitResponse ||
         pkt->req != memReq[tid] ||
-        isSwitchedOut()) {
+        isSwitchedOut() ||
+        drainPending) {
         ++fetchIcacheSquashes;
         delete pkt->req;
         delete pkt;
@@ -384,17 +386,25 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
 
 template <class Impl>
 void
-DefaultFetch<Impl>::switchOut()
+DefaultFetch<Impl>::drain()
 {
-    // Fetch is ready to switch out at any time.
-    switchedOut = true;
-    cpu->signalSwitched();
+    // Fetch is ready to drain at any time.
+    cpu->signalDrained();
+    drainPending = true;
 }
 
 template <class Impl>
 void
-DefaultFetch<Impl>::doSwitchOut()
+DefaultFetch<Impl>::resume()
 {
+    drainPending = false;
+}
+
+template <class Impl>
+void
+DefaultFetch<Impl>::switchOut()
+{
+    switchedOut = true;
     // Branch predictor needs to have its state cleared.
     branchPred.switchOut();
 }
@@ -498,7 +508,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
     unsigned flags = 0;
 #endif // FULL_SYSTEM
 
-    if (cacheBlocked || (interruptPending && flags == 0) || switchedOut) {
+    if (cacheBlocked || (interruptPending && flags == 0) || drainPending) {
         // Hold off fetch from getting new instructions when:
         // Cache is blocked, or
         // while an interrupt is pending and we're not in PAL mode, or
index 9627609c2241e4259096586b20e9751d781311ff..774b6dcbdca02a1660654ef1c5bc8bdd17f308ae 100644 (file)
@@ -143,11 +143,14 @@ class DefaultIEW
     /** Sets pointer to the scoreboard. */
     void setScoreboard(Scoreboard *sb_ptr);
 
-    /** Starts switch out of IEW stage. */
-    void switchOut();
+    /** Drains IEW stage. */
+    void drain();
+
+    /** Resumes execution after a drain. */
+    void resume();
 
     /** Completes switch out of IEW stage. */
-    void doSwitchOut();
+    void switchOut();
 
     /** Takes over from another CPU's thread. */
     void takeOverFrom();
index 118038b651c650719105630b19551c8df85b24ec..c3aa748ae8468163d48882e472d072e313ff0717 100644 (file)
@@ -355,15 +355,21 @@ DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
 
 template <class Impl>
 void
-DefaultIEW<Impl>::switchOut()
+DefaultIEW<Impl>::drain()
 {
-    // IEW is ready to switch out at any time.
-    cpu->signalSwitched();
+    // IEW is ready to drain at any time.
+    cpu->signalDrained();
 }
 
 template <class Impl>
 void
-DefaultIEW<Impl>::doSwitchOut()
+DefaultIEW<Impl>::resume()
+{
+}
+
+template <class Impl>
+void
+DefaultIEW<Impl>::switchOut()
 {
     // Clear any state.
     switchedOut = true;
index 581fc8f8177e446b348c4ab3f709fd76761576f7..538dd9bb43340abe5241340022c660228fd72c6c 100644 (file)
@@ -157,12 +157,15 @@ class DefaultRename
     /** Sets pointer to the scoreboard. */
     void setScoreboard(Scoreboard *_scoreboard);
 
+    /** Drains the rename stage. */
+    void drain();
+
+    /** Resumes execution after a drain. */
+    void resume() { }
+
     /** Switches out the rename stage. */
     void switchOut();
 
-    /** Completes the switch out. */
-    void doSwitchOut();
-
     /** Takes over from another CPU's thread. */
     void takeOverFrom();
 
index df8b7f9dabcbdb6b433fa07d1663f6289527f2d5..fddbae3dba5773d3c648cb6ea952976422349cf8 100644 (file)
@@ -258,15 +258,15 @@ DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
 
 template <class Impl>
 void
-DefaultRename<Impl>::switchOut()
+DefaultRename<Impl>::drain()
 {
     // Rename is ready to switch out at any time.
-    cpu->signalSwitched();
+    cpu->signalDrained();
 }
 
 template <class Impl>
 void
-DefaultRename<Impl>::doSwitchOut()
+DefaultRename<Impl>::switchOut()
 {
     // Clear any state, fix up the rename map.
     for (int i = 0; i < numThreads; i++) {