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:
parent
3eb04b4ad7
commit
90d3b45a56
5 changed files with 51 additions and 3 deletions
|
@ -674,6 +674,8 @@ InOrderCPU::activateNextReadyThread()
|
||||||
DPRINTF(InOrderCPU,
|
DPRINTF(InOrderCPU,
|
||||||
"Attempting to activate new thread, but No Ready Threads to"
|
"Attempting to activate new thread, but No Ready Threads to"
|
||||||
"activate.\n");
|
"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 "
|
"Ignoring activation of [tid:%i], since [tid:%i] is "
|
||||||
"already running.\n", tid, activeThreadId());
|
"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);
|
tid);
|
||||||
|
|
||||||
readyThreads.push_back(tid);
|
readyThreads.push_back(tid);
|
||||||
|
@ -706,10 +708,20 @@ InOrderCPU::activateThread(ThreadID tid)
|
||||||
"Adding [tid:%i] to active threads list.\n", tid);
|
"Adding [tid:%i] to active threads list.\n", tid);
|
||||||
activeThreads.push_back(tid);
|
activeThreads.push_back(tid);
|
||||||
|
|
||||||
|
activateThreadInPipeline(tid);
|
||||||
|
|
||||||
wakeCPU();
|
wakeCPU();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InOrderCPU::activateThreadInPipeline(ThreadID tid)
|
||||||
|
{
|
||||||
|
for (int stNum=0; stNum < NumStages; stNum++) {
|
||||||
|
pipelineStage[stNum]->activateThread(tid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InOrderCPU::deactivateContext(ThreadID tid, int delay)
|
InOrderCPU::deactivateContext(ThreadID tid, int delay)
|
||||||
{
|
{
|
||||||
|
|
|
@ -346,7 +346,8 @@ class InOrderCPU : public BaseCPU
|
||||||
/** Add Thread to Active Threads List. */
|
/** Add Thread to Active Threads List. */
|
||||||
void activateContext(ThreadID tid, int delay = 0);
|
void activateContext(ThreadID tid, int delay = 0);
|
||||||
void activateThread(ThreadID tid);
|
void activateThread(ThreadID tid);
|
||||||
|
void activateThreadInPipeline(ThreadID tid);
|
||||||
|
|
||||||
/** Add Thread to Active Threads List. */
|
/** Add Thread to Active Threads List. */
|
||||||
void activateNextReadyContext(int delay = 0);
|
void activateNextReadyContext(int delay = 0);
|
||||||
void activateNextReadyThread();
|
void activateNextReadyThread();
|
||||||
|
|
|
@ -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
|
void
|
||||||
|
@ -945,6 +967,11 @@ PipelineStage::processInstSchedule(DynInstPtr inst)
|
||||||
if (req->isMemStall() &&
|
if (req->isMemStall() &&
|
||||||
cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
|
cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
|
||||||
// Save Stalling Instruction
|
// 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;
|
switchedOutBuffer[tid] = inst;
|
||||||
switchedOutValid[tid] = true;
|
switchedOutValid[tid] = true;
|
||||||
|
|
||||||
|
@ -956,9 +983,12 @@ PipelineStage::processInstSchedule(DynInstPtr inst)
|
||||||
// Switch On Cache Miss
|
// Switch On Cache Miss
|
||||||
//=====================
|
//=====================
|
||||||
// Suspend Thread at end of cycle
|
// Suspend Thread at end of cycle
|
||||||
|
DPRINTF(ThreadModel, "Suspending [tid:%i] due to cache miss.\n", tid);
|
||||||
cpu->suspendContext(tid);
|
cpu->suspendContext(tid);
|
||||||
|
|
||||||
// Activate Next Ready Thread at end of cycle
|
// Activate Next Ready Thread at end of cycle
|
||||||
|
DPRINTF(ThreadModel, "Attempting to activate next ready thread due to"
|
||||||
|
" cache miss.\n");
|
||||||
cpu->activateNextReadyContext();
|
cpu->activateNextReadyContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,6 +235,8 @@ class PipelineStage
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual void activateThread(ThreadID tid);
|
||||||
|
|
||||||
/** Squashes if there is a PC-relative branch that was predicted
|
/** Squashes if there is a PC-relative branch that was predicted
|
||||||
* incorrectly. Sends squash information back to fetch.
|
* incorrectly. Sends squash information back to fetch.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -708,9 +708,12 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
|
||||||
|
|
||||||
if (cache_req->isMemStall() &&
|
if (cache_req->isMemStall() &&
|
||||||
cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
|
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);
|
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
|
// Wake up the CPU (if it went to sleep and was waiting on this
|
||||||
|
|
Loading…
Reference in a new issue