inorder: suspend in respool
authorKorey Sewell <ksewell@umich.edu>
Sun, 31 Jan 2010 23:27:02 +0000 (18:27 -0500)
committerKorey Sewell <ksewell@umich.edu>
Sun, 31 Jan 2010 23:27:02 +0000 (18:27 -0500)
give resources their own specific
activity to do for a "suspend" event
instead of defaulting to deactivating the thread for a
suspend thread event. This really matters
for the fetch sequence unit which wants to remove the
thread from fetching while other units want to
ignore a thread suspension. If you deactivate a thread
in a resource then you may lose some of the allotted
bandwidth that the thread is taking up...

src/cpu/inorder/resource.hh
src/cpu/inorder/resource_pool.cc
src/cpu/inorder/resource_pool.hh
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/fetch_seq_unit.cc
src/cpu/inorder/resources/fetch_seq_unit.hh

index f7c4b8fcd728b9ff96da3170fca0bf2e62f94e31..4ae4db818c774876e775c06774a7c42089994f4e 100644 (file)
@@ -93,6 +93,10 @@ class Resource {
      */
     virtual void deactivateThread(ThreadID tid);
 
+    /** Resources that care about thread activation override this. */
+    virtual void suspendThread(ThreadID tid) { }
+    
+
     /** Resources that care when an instruction has been graduated
      *  can override this
      */
index 97ba4d08754549c604b231205522ecdf4ae97437..45a4a9e6000211ecda14e8baae34e4bb6e80205d 100644 (file)
@@ -226,7 +226,7 @@ ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst,
         }
         break;
 
-      case InOrderCPU::SuspendThread:
+      case InOrderCPU::DeactivateThread:
       case InOrderCPU::DeallocateThread:
         {
 
@@ -246,6 +246,23 @@ ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type, DynInstPtr inst,
         }
         break;
 
+      case InOrderCPU::SuspendThread:
+        {
+
+            DPRINTF(Resource, "Scheduling Suspend Thread Resource Pool Event for tick %i.\n",
+                    curTick + delay);
+            ResPoolEvent *res_pool_event = new ResPoolEvent(this,
+                                                            e_type,
+                                                            inst,
+                                                            inst->squashingStage,
+                                                            inst->bdelaySeqNum,
+                                                            tid);
+
+            mainEventQueue.schedule(res_pool_event, curTick + cpu->ticks(delay));
+
+        }
+        break;
+
       case ResourcePool::InstGraduated:
         {
             DPRINTF(Resource, "Scheduling Inst-Graduated Resource Pool "
@@ -309,8 +326,9 @@ void
 ResourcePool::squashAll(DynInstPtr inst, int stage_num,
                         InstSeqNum done_seq_num, ThreadID tid)
 {
-    DPRINTF(Resource, "[tid:%i] Stage %i squashing all instructions above "
-            "[sn:%i].\n", tid, stage_num, done_seq_num);
+    DPRINTF(Resource, "[tid:%i] Broadcasting Squash All Event "
+            " starting w/stage %i for all instructions above [sn:%i].\n",
+             tid, stage_num, done_seq_num);
 
     int num_resources = resources.size();
 
@@ -323,8 +341,9 @@ void
 ResourcePool::squashDueToMemStall(DynInstPtr inst, int stage_num,
                              InstSeqNum done_seq_num, ThreadID tid)
 {
-    DPRINTF(Resource, "[tid:%i] Stage %i squashing all instructions above "
-            "[sn:%i].\n", stage_num, tid, done_seq_num);
+    DPRINTF(Resource, "[tid:%i] Broadcasting SquashDueToMemStall Event"
+            " starting w/stage %i for all instructions above [sn:%i].\n",
+            tid, stage_num, done_seq_num);
 
     int num_resources = resources.size();
 
@@ -370,6 +389,19 @@ ResourcePool::deactivateAll(ThreadID tid)
     }
 }
 
+void
+ResourcePool::suspendAll(ThreadID tid)
+{
+    DPRINTF(Resource, "[tid:%i] Broadcasting Thread Suspension to all resources.\n",
+            tid);
+
+    int num_resources = resources.size();
+
+    for (int idx = 0; idx < num_resources; idx++) {
+        resources[idx]->suspendThread(tid);
+    }
+}
+
 void
 ResourcePool::instGraduated(InstSeqNum seq_num, ThreadID tid)
 {
@@ -409,11 +441,15 @@ ResourcePool::ResPoolEvent::process()
         resPool->activateAll(tid);
         break;
 
-      case InOrderCPU::SuspendThread:
+      case InOrderCPU::DeactivateThread:
       case InOrderCPU::DeallocateThread:
         resPool->deactivateAll(tid);
         break;
 
+      case InOrderCPU::SuspendThread:
+        resPool->suspendAll(tid);
+        break;
+
       case ResourcePool::InstGraduated:
         resPool->instGraduated(seqNum, tid);
         break;
index 61e691f350fd8ad094a962db17c36e19474ed674..ae63c4c593d26c64e2e6362c32d8a78f168a15fd 100644 (file)
@@ -172,6 +172,9 @@ class ResourcePool {
     /** De-Activate Thread in all resources */
     void deactivateAll(ThreadID tid);
 
+    /** De-Activate Thread in all resources */
+    void suspendAll(ThreadID tid);
+
     /** Broadcast graduation to all resources */
     void instGraduated(InstSeqNum seq_num, ThreadID tid);
 
index 570d27fbef04f7a48bf1e535e40141d0ea7c4833..8f92db3e4c99caa1150d448bd4d31c5acf351eaf 100644 (file)
@@ -158,9 +158,9 @@ CacheUnit::getSlot(DynInstPtr inst)
         return new_slot;
     } else {
         DPRINTF(InOrderCachePort,
-                "Denying request because there is an outstanding"
+                "[tid:%i] Denying request because there is an outstanding"
                 " request to/for addr. %08p. by [sn:%i] @ tick %i\n",
-                req_addr, addrMap[req_addr], inst->memTime);
+                inst->readTid(), req_addr, addrMap[req_addr], inst->memTime);
         return -1;
     }
 }
@@ -702,6 +702,13 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
         cache_req->setMemAccPending(false);
         cache_req->setMemAccCompleted();
 
+        if (cache_req->isMemStall() && 
+            cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {    
+            DPRINTF(InOrderCachePort, "[tid:%u] Waking up from Cache Miss.\n");
+            
+            cpu->activateContext(tid);            
+        }
+        
         // Wake up the CPU (if it went to sleep and was waiting on this
         // completion event).
         cpu->wakeCPU();
@@ -784,6 +791,9 @@ CacheUnit::squashDueToMemStall(DynInstPtr inst, int stage_num,
     //       thread then you need to reevaluate this code
     // NOTE: squash should originate from 
     //       pipeline_stage.cc:processInstSchedule
+    DPRINTF(InOrderCachePort, "Squashing above [sn:%u]\n", 
+            squash_seq_num + 1);
+    
     squash(inst, stage_num, squash_seq_num + 1, tid);    
 }
 
index 1d0b9207523bddc1ae5f47575db5152f0f277eb9..e0b9ea1f96f5b5c86cd33e7d3b6e5704728f9741 100644 (file)
@@ -336,3 +336,9 @@ FetchSeqUnit::deactivateThread(ThreadID tid)
     if (thread_it != cpu->fetchPriorityList.end())
         cpu->fetchPriorityList.erase(thread_it);
 }
+
+void
+FetchSeqUnit::suspendThread(ThreadID tid)
+{
+    deactivateThread(tid);    
+}
index a4495564b6a4e333df637eae917b663f8f6e1055..fdbc4521f989862ed6b0269f01f311fe393f7b55 100644 (file)
@@ -59,6 +59,7 @@ class FetchSeqUnit : public Resource {
     virtual void init();
     virtual void activateThread(ThreadID tid);
     virtual void deactivateThread(ThreadID tid);
+    virtual void suspendThread(ThreadID tid);
     virtual void execute(int slot_num);
 
     /** Override default Resource squash sequence. This actually,