diff options
author | Korey Sewell <ksewell@umich.edu> | 2010-01-31 18:27:38 -0500 |
---|---|---|
committer | Korey Sewell <ksewell@umich.edu> | 2010-01-31 18:27:38 -0500 |
commit | 90d3b45a566847fe15095b92238e32973ad9cc0e (patch) | |
tree | 9deb58c0889ec67a5aefdf66cf90c1cd9c311b04 /src/cpu/inorder | |
parent | 3eb04b4ad73cb66e86d09ffd5989a93d9f62b299 (diff) | |
download | gem5-90d3b45a566847fe15095b92238e32973ad9cc0e.tar.xz |
inorder: ready thread wakeup
allow a thread to wakeup and be activated after
it has been in suspended state and another
thread is switched out. Need to give
pipeline stages a "activateThread" function
so that can get to their suspended instruction
when the time is right.
Diffstat (limited to 'src/cpu/inorder')
-rw-r--r-- | src/cpu/inorder/cpu.cc | 14 | ||||
-rw-r--r-- | src/cpu/inorder/cpu.hh | 3 | ||||
-rw-r--r-- | src/cpu/inorder/pipeline_stage.cc | 30 | ||||
-rw-r--r-- | src/cpu/inorder/pipeline_stage.hh | 2 | ||||
-rw-r--r-- | src/cpu/inorder/resources/cache_unit.cc | 5 |
5 files changed, 51 insertions, 3 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index ec6bb21ee..501150386 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -674,6 +674,8 @@ InOrderCPU::activateNextReadyThread() DPRINTF(InOrderCPU, "Attempting to activate new thread, but No Ready Threads to" "activate.\n"); + DPRINTF(InOrderCPU, + "Unable to switch to next active thread.\n"); } } @@ -696,7 +698,7 @@ InOrderCPU::activateThread(ThreadID tid) "Ignoring activation of [tid:%i], since [tid:%i] is " "already running.\n", tid, activeThreadId()); - DPRINTF(InOrderCPU,"Placing [tid:%i] ready threads list\n", + DPRINTF(InOrderCPU,"Placing [tid:%i] on ready threads list\n", tid); readyThreads.push_back(tid); @@ -706,11 +708,21 @@ InOrderCPU::activateThread(ThreadID tid) "Adding [tid:%i] to active threads list.\n", tid); activeThreads.push_back(tid); + activateThreadInPipeline(tid); + wakeCPU(); } } void +InOrderCPU::activateThreadInPipeline(ThreadID tid) +{ + for (int stNum=0; stNum < NumStages; stNum++) { + pipelineStage[stNum]->activateThread(tid); + } +} + +void InOrderCPU::deactivateContext(ThreadID tid, int delay) { DPRINTF(InOrderCPU,"[tid:%i]: Deactivating ...\n", tid); diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index 7ac433723..1e514e1ed 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -346,7 +346,8 @@ class InOrderCPU : public BaseCPU /** Add Thread to Active Threads List. */ void activateContext(ThreadID tid, int delay = 0); void activateThread(ThreadID tid); - + void activateThreadInPipeline(ThreadID tid); + /** Add Thread to Active Threads List. */ void activateNextReadyContext(int delay = 0); void activateNextReadyThread(); diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 30a3733b0..ef91f206b 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -558,6 +558,28 @@ PipelineStage::updateStatus() } } +void +PipelineStage::activateThread(ThreadID tid) +{ + if (cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) { + if (!switchedOutValid[tid]) { + DPRINTF(InOrderStage, "[tid:%i] No instruction available in " + "switch out buffer.\n", tid); + } else { + DynInstPtr inst = switchedOutBuffer[tid]; + + DPRINTF(InOrderStage,"[tid:%i]: Re-Inserting [sn:%lli] PC:%#x into stage skidBuffer %i\n", + tid, inst->seqNum, inst->readPC(), inst->threadNumber); + + skidBuffer[tid].push(inst); + + switchedOutBuffer[tid] = NULL; + + switchedOutValid[tid] = false; + } + } + +} void @@ -945,6 +967,11 @@ PipelineStage::processInstSchedule(DynInstPtr inst) if (req->isMemStall() && cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) { // Save Stalling Instruction + DPRINTF(ThreadModel, "[tid:%i] Detected cache miss.\n", tid); + + DPRINTF(InOrderStage, "Inserting [tid:%i][sn:%i] into switch out buffer.\n", + tid, inst->seqNum); + switchedOutBuffer[tid] = inst; switchedOutValid[tid] = true; @@ -956,9 +983,12 @@ PipelineStage::processInstSchedule(DynInstPtr inst) // Switch On Cache Miss //===================== // Suspend Thread at end of cycle + DPRINTF(ThreadModel, "Suspending [tid:%i] due to cache miss.\n", tid); cpu->suspendContext(tid); // Activate Next Ready Thread at end of cycle + DPRINTF(ThreadModel, "Attempting to activate next ready thread due to" + " cache miss.\n"); cpu->activateNextReadyContext(); } diff --git a/src/cpu/inorder/pipeline_stage.hh b/src/cpu/inorder/pipeline_stage.hh index f10906e4c..dfe1ac7c3 100644 --- a/src/cpu/inorder/pipeline_stage.hh +++ b/src/cpu/inorder/pipeline_stage.hh @@ -235,6 +235,8 @@ class PipelineStage public: + virtual void activateThread(ThreadID tid); + /** Squashes if there is a PC-relative branch that was predicted * incorrectly. Sends squash information back to fetch. */ diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 3de5c518a..2cf6c3195 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -708,9 +708,12 @@ CacheUnit::processCacheCompletion(PacketPtr pkt) if (cache_req->isMemStall() && cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) { - DPRINTF(InOrderCachePort, "[tid:%u] Waking up from Cache Miss.\n"); + DPRINTF(InOrderCachePort, "[tid:%u] Waking up from Cache Miss.\n", tid); cpu->activateContext(tid); + + DPRINTF(ThreadModel, "Activating [tid:%i] after return from cache" + "miss.\n", tid); } // Wake up the CPU (if it went to sleep and was waiting on this |