diff -r 6aeafefcf610 -r 5d7be2fc04c7 src/cpu/o3/commit_impl.hh --- a/src/cpu/o3/commit_impl.hh Thu Jun 06 07:18:19 2013 -0500 +++ b/src/cpu/o3/commit_impl.hh Fri Jun 07 17:53:56 2013 -0500 @@ -407,8 +407,10 @@ * address mappings. This can happen on for example x86. */ for (ThreadID tid = 0; tid < numThreads; tid++) { - if (pc[tid].microPC() != 0) + if (commitStatus[tid] != Idle && pc[tid].microPC() != 0) { + DPRINTF(Drain, "microPC = %s\n", pc[tid].microPC()); return false; + } } /* Make sure that all instructions have finished committing before diff -r 6aeafefcf610 -r 5d7be2fc04c7 src/cpu/o3/cpu.cc --- a/src/cpu/o3/cpu.cc Thu Jun 06 07:18:19 2013 -0500 +++ b/src/cpu/o3/cpu.cc Fri Jun 07 17:53:56 2013 -0500 @@ -773,7 +773,7 @@ // Be sure to signal that there's some activity so the CPU doesn't // deschedule itself. activityRec.activity(); - fetch.wakeFromQuiesce(); + fetch.wakeFromQuiesce(tid); Cycles cycles(curCycle() - lastRunningCycle); // @todo: This is an oddity that is only here to match the stats diff -r 6aeafefcf610 -r 5d7be2fc04c7 src/cpu/o3/fetch.hh --- a/src/cpu/o3/fetch.hh Thu Jun 06 07:18:19 2013 -0500 +++ b/src/cpu/o3/fetch.hh Fri Jun 07 17:53:56 2013 -0500 @@ -249,7 +249,7 @@ void drainStall(ThreadID tid); /** Tells fetch to wake up from a quiesce instruction. */ - void wakeFromQuiesce(); + void wakeFromQuiesce(ThreadID tid); private: /** Reset this pipeline stage */ diff -r 6aeafefcf610 -r 5d7be2fc04c7 src/cpu/o3/fetch_impl.hh --- a/src/cpu/o3/fetch_impl.hh Thu Jun 06 07:18:19 2013 -0500 +++ b/src/cpu/o3/fetch_impl.hh Fri Jun 07 17:53:56 2013 -0500 @@ -317,7 +317,7 @@ // Setup PC and nextPC with initial state. for (ThreadID tid = 0; tid < numThreads; tid++) { - fetchStatus[tid] = Running; + fetchStatus[tid] = Idle; pc[tid] = cpu->pcState(tid); fetchOffset[tid] = 0; macroop[tid] = NULL; @@ -469,7 +469,6 @@ { assert(cpu->getInstPort().isConnected()); resetStage(); - } template @@ -484,12 +483,11 @@ template void -DefaultFetch::wakeFromQuiesce() +DefaultFetch::wakeFromQuiesce(ThreadID tid) { DPRINTF(Fetch, "Waking up from quiesce\n"); // Hopefully this is safe - // @todo: Allow other threads to wake from quiesce. - fetchStatus[0] = Running; + fetchStatus[tid] = Running; } template diff -r 6aeafefcf610 -r 5d7be2fc04c7 src/cpu/simple/atomic.cc --- a/src/cpu/simple/atomic.cc Thu Jun 06 07:18:19 2013 -0500 +++ b/src/cpu/simple/atomic.cc Fri Jun 07 17:53:56 2013 -0500 @@ -144,16 +144,21 @@ if (switchedOut()) return 0; - if (!isDrained()) { - DPRINTF(Drain, "Requesting drain: %s\n", pcState()); - drain_manager = dm; - return 1; + if (_status == Idle) { + DPRINTF(Drain, "Idle, no need to drain.\n"); + return 0; } else { - if (tickEvent.scheduled()) - deschedule(tickEvent); + if (!isDrained()) { + DPRINTF(Drain, "Requesting drain: %s\n", pcState()); + drain_manager = dm; + return 1; + } else { + if (tickEvent.scheduled()) + deschedule(tickEvent); - DPRINTF(Drain, "Not executing microcode, no need to drain.\n"); - return 0; + DPRINTF(Drain, "Not executing microcode, no need to drain.\n"); + return 0; + } } } @@ -203,11 +208,12 @@ void AtomicSimpleCPU::switchOut() { + DPRINTF(Drain, "SwitchingOut: %s\n", pcState()); BaseSimpleCPU::switchOut(); assert(!tickEvent.scheduled()); - assert(_status == BaseSimpleCPU::Running || _status == Idle); - assert(isDrained()); + assert((_status == BaseSimpleCPU::Running && isDrained()) || + _status == Idle); } diff -r 6aeafefcf610 -r 5d7be2fc04c7 src/cpu/simple/timing.cc --- a/src/cpu/simple/timing.cc Thu Jun 06 07:18:19 2013 -0500 +++ b/src/cpu/simple/timing.cc Fri Jun 07 17:53:56 2013 -0500 @@ -172,9 +172,8 @@ BaseSimpleCPU::switchOut(); assert(!fetchEvent.scheduled()); - assert(_status == BaseSimpleCPU::Running || _status == Idle); - assert(!stayAtPC); - assert(microPC() == 0); + assert(_status == Idle || + (_status == BaseSimpleCPU::Running && isDrained())); numCycles += curCycle() - previousCycle; }