Fix the O3CPU to support the multi-pass method for checking if the system has fully drained.
src/cpu/o3/commit.hh:
src/cpu/o3/commit_impl.hh:
src/cpu/o3/decode.hh:
src/cpu/o3/decode_impl.hh:
src/cpu/o3/fetch.hh:
src/cpu/o3/fetch_impl.hh:
src/cpu/o3/iew.hh:
src/cpu/o3/iew_impl.hh:
src/cpu/o3/rename.hh:
src/cpu/o3/rename_impl.hh:
Return a value so that the CPU can instantly return from draining if the pipeline is already drained.
src/cpu/o3/cpu.cc:
Use values returned from pipeline stages so that the CPU can instantly return from draining if the pipeline is already drained.
--HG--
extra : convert_revision : d8ef6b811644ea67c8b40c4719273fa224105811
This commit is contained in:
@@ -188,7 +188,7 @@ class DefaultCommit
|
||||
void initStage();
|
||||
|
||||
/** Initializes the draining of commit. */
|
||||
void drain();
|
||||
bool drain();
|
||||
|
||||
/** Resumes execution after draining. */
|
||||
void resume();
|
||||
|
||||
@@ -350,10 +350,18 @@ DefaultCommit<Impl>::initStage()
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
bool
|
||||
DefaultCommit<Impl>::drain()
|
||||
{
|
||||
drainPending = true;
|
||||
|
||||
// If it's already drained, return true.
|
||||
if (rob->isEmpty() && !iewStage->hasStoresToWB()) {
|
||||
cpu->signalDrained();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -712,19 +712,27 @@ bool
|
||||
FullO3CPU<Impl>::drain(Event *drain_event)
|
||||
{
|
||||
drainCount = 0;
|
||||
drainEvent = drain_event;
|
||||
fetch.drain();
|
||||
decode.drain();
|
||||
rename.drain();
|
||||
iew.drain();
|
||||
commit.drain();
|
||||
// A bit of a hack...set the drainEvent after all the drain()
|
||||
// calls have been made, that way if all of the stages drain
|
||||
// immediately, the signalDrained() function knows not to call
|
||||
// process on the drain event.
|
||||
drainEvent = drain_event;
|
||||
|
||||
// Wake the CPU and record activity so everything can drain out if
|
||||
// the CPU is currently idle.
|
||||
wakeCPU();
|
||||
activityRec.activity();
|
||||
// the CPU was not able to immediately drain.
|
||||
if (_status != Drained) {
|
||||
wakeCPU();
|
||||
activityRec.activity();
|
||||
|
||||
return false;
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
@@ -751,8 +759,13 @@ FullO3CPU<Impl>::signalDrained()
|
||||
if (++drainCount == NumStages) {
|
||||
if (tickEvent.scheduled())
|
||||
tickEvent.squash();
|
||||
|
||||
_status = Drained;
|
||||
drainEvent->process();
|
||||
|
||||
if (drainEvent) {
|
||||
drainEvent->process();
|
||||
drainEvent = NULL;
|
||||
}
|
||||
}
|
||||
assert(drainCount <= 5);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ class DefaultDecode
|
||||
void setActiveThreads(std::list<unsigned> *at_ptr);
|
||||
|
||||
/** Drains the decode stage. */
|
||||
void drain();
|
||||
bool drain();
|
||||
|
||||
/** Resumes execution after a drain. */
|
||||
void resume() { }
|
||||
|
||||
@@ -165,11 +165,12 @@ DefaultDecode<Impl>::setActiveThreads(list<unsigned> *at_ptr)
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
bool
|
||||
DefaultDecode<Impl>::drain()
|
||||
{
|
||||
// Decode is done draining at any time.
|
||||
cpu->signalDrained();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -181,7 +181,7 @@ class DefaultFetch
|
||||
void processCacheCompletion(PacketPtr pkt);
|
||||
|
||||
/** Begins the drain of the fetch stage. */
|
||||
void drain();
|
||||
bool drain();
|
||||
|
||||
/** Resumes execution after a drain. */
|
||||
void resume();
|
||||
|
||||
@@ -385,12 +385,13 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
bool
|
||||
DefaultFetch<Impl>::drain()
|
||||
{
|
||||
// Fetch is ready to drain at any time.
|
||||
cpu->signalDrained();
|
||||
drainPending = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -144,7 +144,7 @@ class DefaultIEW
|
||||
void setScoreboard(Scoreboard *sb_ptr);
|
||||
|
||||
/** Drains IEW stage. */
|
||||
void drain();
|
||||
bool drain();
|
||||
|
||||
/** Resumes execution after a drain. */
|
||||
void resume();
|
||||
|
||||
@@ -354,11 +354,12 @@ DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
bool
|
||||
DefaultIEW<Impl>::drain()
|
||||
{
|
||||
// IEW is ready to drain at any time.
|
||||
cpu->signalDrained();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
@@ -158,7 +158,7 @@ class DefaultRename
|
||||
void setScoreboard(Scoreboard *_scoreboard);
|
||||
|
||||
/** Drains the rename stage. */
|
||||
void drain();
|
||||
bool drain();
|
||||
|
||||
/** Resumes execution after a drain. */
|
||||
void resume() { }
|
||||
|
||||
@@ -257,11 +257,12 @@ DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
bool
|
||||
DefaultRename<Impl>::drain()
|
||||
{
|
||||
// Rename is ready to switch out at any time.
|
||||
cpu->signalDrained();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
||||
Reference in New Issue
Block a user