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.
This commit is contained in:
Korey Sewell 2010-01-31 18:27:38 -05:00
parent 3eb04b4ad7
commit 90d3b45a56
5 changed files with 51 additions and 3 deletions

View file

@ -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,10 +708,20 @@ 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)
{

View file

@ -346,6 +346,7 @@ 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);

View file

@ -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();
}

View file

@ -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.
*/

View file

@ -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