Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/newmem-merge --HG-- extra : convert_revision : 00f8eecf99c771ae8943ed1d3a652bfbcfe1c6bc
This commit is contained in:
commit
05eef5ee15
|
@ -187,11 +187,14 @@ class DefaultCommit
|
|||
/** Initializes stage by sending back the number of free entries. */
|
||||
void initStage();
|
||||
|
||||
/** Initializes the switching out of commit. */
|
||||
void switchOut();
|
||||
/** Initializes the draining of commit. */
|
||||
void drain();
|
||||
|
||||
/** Resumes execution after draining. */
|
||||
void resume();
|
||||
|
||||
/** Completes the switch out of commit. */
|
||||
void doSwitchOut();
|
||||
void switchOut();
|
||||
|
||||
/** Takes over from another CPU's thread. */
|
||||
void takeOverFrom();
|
||||
|
@ -383,8 +386,8 @@ class DefaultCommit
|
|||
/** Number of Active Threads */
|
||||
unsigned numThreads;
|
||||
|
||||
/** Is a switch out pending. */
|
||||
bool switchPending;
|
||||
/** Is a drain pending. */
|
||||
bool drainPending;
|
||||
|
||||
/** Is commit switched out. */
|
||||
bool switchedOut;
|
||||
|
|
|
@ -80,7 +80,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
|
|||
renameWidth(params->renameWidth),
|
||||
commitWidth(params->commitWidth),
|
||||
numThreads(params->numberOfThreads),
|
||||
switchPending(false),
|
||||
drainPending(false),
|
||||
switchedOut(false),
|
||||
trapLatency(params->trapLatency),
|
||||
fetchTrapLatency(params->fetchTrapLatency)
|
||||
|
@ -351,20 +351,26 @@ DefaultCommit<Impl>::initStage()
|
|||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultCommit<Impl>::switchOut()
|
||||
DefaultCommit<Impl>::drain()
|
||||
{
|
||||
switchPending = true;
|
||||
drainPending = true;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultCommit<Impl>::doSwitchOut()
|
||||
DefaultCommit<Impl>::switchOut()
|
||||
{
|
||||
switchedOut = true;
|
||||
switchPending = false;
|
||||
drainPending = false;
|
||||
rob->switchOut();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultCommit<Impl>::resume()
|
||||
{
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultCommit<Impl>::takeOverFrom()
|
||||
|
@ -557,8 +563,9 @@ DefaultCommit<Impl>::tick()
|
|||
wroteToTimeBuffer = false;
|
||||
_nextStatus = Inactive;
|
||||
|
||||
if (switchPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
|
||||
cpu->signalSwitched();
|
||||
if (drainPending && rob->isEmpty() && !iewStage->hasStoresToWB()) {
|
||||
cpu->signalDrained();
|
||||
drainPending = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
|
|||
physmem(system->physmem),
|
||||
#endif // FULL_SYSTEM
|
||||
mem(params->mem),
|
||||
switchCount(0),
|
||||
drainCount(0),
|
||||
deferRegistration(params->deferRegistration),
|
||||
numThreads(number_of_threads)
|
||||
{
|
||||
|
@ -708,45 +708,72 @@ FullO3CPU<Impl>::haltContext(int tid)
|
|||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::switchOut()
|
||||
bool
|
||||
FullO3CPU<Impl>::drain(Event *drain_event)
|
||||
{
|
||||
switchCount = 0;
|
||||
fetch.switchOut();
|
||||
decode.switchOut();
|
||||
rename.switchOut();
|
||||
iew.switchOut();
|
||||
commit.switchOut();
|
||||
drainCount = 0;
|
||||
drainEvent = drain_event;
|
||||
fetch.drain();
|
||||
decode.drain();
|
||||
rename.drain();
|
||||
iew.drain();
|
||||
commit.drain();
|
||||
|
||||
// Wake the CPU and record activity so everything can drain out if
|
||||
// the CPU is currently idle.
|
||||
wakeCPU();
|
||||
activityRec.activity();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::signalSwitched()
|
||||
FullO3CPU<Impl>::resume()
|
||||
{
|
||||
if (++switchCount == NumStages) {
|
||||
fetch.doSwitchOut();
|
||||
rename.doSwitchOut();
|
||||
commit.doSwitchOut();
|
||||
instList.clear();
|
||||
while (!removeList.empty()) {
|
||||
removeList.pop();
|
||||
}
|
||||
if (_status == SwitchedOut)
|
||||
return;
|
||||
fetch.resume();
|
||||
decode.resume();
|
||||
rename.resume();
|
||||
iew.resume();
|
||||
commit.resume();
|
||||
|
||||
#if USE_CHECKER
|
||||
if (checker)
|
||||
checker->switchOut();
|
||||
#endif
|
||||
if (!tickEvent.scheduled())
|
||||
tickEvent.schedule(curTick);
|
||||
_status = Running;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::signalDrained()
|
||||
{
|
||||
if (++drainCount == NumStages) {
|
||||
if (tickEvent.scheduled())
|
||||
tickEvent.squash();
|
||||
_status = SwitchedOut;
|
||||
_status = Drained;
|
||||
drainEvent->process();
|
||||
}
|
||||
assert(switchCount <= 5);
|
||||
assert(drainCount <= 5);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
FullO3CPU<Impl>::switchOut()
|
||||
{
|
||||
fetch.switchOut();
|
||||
rename.switchOut();
|
||||
commit.switchOut();
|
||||
instList.clear();
|
||||
while (!removeList.empty()) {
|
||||
removeList.pop();
|
||||
}
|
||||
|
||||
_status = SwitchedOut;
|
||||
#if USE_CHECKER
|
||||
if (checker)
|
||||
checker->switchOut();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
|
|
@ -57,6 +57,8 @@ class Checker;
|
|||
class ThreadContext;
|
||||
template <class>
|
||||
class O3ThreadContext;
|
||||
|
||||
class Checkpoint;
|
||||
class MemObject;
|
||||
class Process;
|
||||
|
||||
|
@ -109,6 +111,7 @@ class FullO3CPU : public BaseO3CPU
|
|||
Idle,
|
||||
Halted,
|
||||
Blocked,
|
||||
Drained,
|
||||
SwitchedOut
|
||||
};
|
||||
|
||||
|
@ -270,14 +273,21 @@ class FullO3CPU : public BaseO3CPU
|
|||
*/
|
||||
virtual void syscall(int tid) { panic("Unimplemented!"); }
|
||||
|
||||
/** Switches out this CPU. */
|
||||
void switchOut();
|
||||
/** Starts draining the CPU's pipeline of all instructions in
|
||||
* order to stop all memory accesses. */
|
||||
virtual bool drain(Event *drain_event);
|
||||
|
||||
/** Resumes execution after a drain. */
|
||||
virtual void resume();
|
||||
|
||||
/** Signals to this CPU that a stage has completed switching out. */
|
||||
void signalSwitched();
|
||||
void signalDrained();
|
||||
|
||||
/** Switches out this CPU. */
|
||||
virtual void switchOut();
|
||||
|
||||
/** Takes over from another CPU. */
|
||||
void takeOverFrom(BaseCPU *oldCPU);
|
||||
virtual void takeOverFrom(BaseCPU *oldCPU);
|
||||
|
||||
/** Get the current instruction sequence number, and increment it. */
|
||||
InstSeqNum getAndIncrementInstSeq()
|
||||
|
@ -550,8 +560,11 @@ class FullO3CPU : public BaseO3CPU
|
|||
/** Pointer to memory. */
|
||||
MemObject *mem;
|
||||
|
||||
/** Counter of how many stages have completed switching out. */
|
||||
int switchCount;
|
||||
/** Event to call process() on once draining has completed. */
|
||||
Event *drainEvent;
|
||||
|
||||
/** Counter of how many stages have completed draining. */
|
||||
int drainCount;
|
||||
|
||||
/** Pointers to all of the threads in the CPU. */
|
||||
std::vector<Thread *> thread;
|
||||
|
|
|
@ -109,8 +109,14 @@ class DefaultDecode
|
|||
/** Sets pointer to list of active threads. */
|
||||
void setActiveThreads(std::list<unsigned> *at_ptr);
|
||||
|
||||
/** Drains the decode stage. */
|
||||
void drain();
|
||||
|
||||
/** Resumes execution after a drain. */
|
||||
void resume() { }
|
||||
|
||||
/** Switches out the decode stage. */
|
||||
void switchOut();
|
||||
void switchOut() { }
|
||||
|
||||
/** Takes over from another CPU's thread. */
|
||||
void takeOverFrom();
|
||||
|
|
|
@ -166,10 +166,10 @@ DefaultDecode<Impl>::setActiveThreads(list<unsigned> *at_ptr)
|
|||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultDecode<Impl>::switchOut()
|
||||
DefaultDecode<Impl>::drain()
|
||||
{
|
||||
// Decode can immediately switch out.
|
||||
cpu->signalSwitched();
|
||||
// Decode is done draining at any time.
|
||||
cpu->signalDrained();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
|
|
|
@ -180,11 +180,14 @@ class DefaultFetch
|
|||
/** Processes cache completion event. */
|
||||
void processCacheCompletion(PacketPtr pkt);
|
||||
|
||||
/** Begins the switch out of the fetch stage. */
|
||||
void switchOut();
|
||||
/** Begins the drain of the fetch stage. */
|
||||
void drain();
|
||||
|
||||
/** Completes the switch out of the fetch stage. */
|
||||
void doSwitchOut();
|
||||
/** Resumes execution after a drain. */
|
||||
void resume();
|
||||
|
||||
/** Tells fetch stage to prepare to be switched out. */
|
||||
void switchOut();
|
||||
|
||||
/** Takes over from another CPU's thread. */
|
||||
void takeOverFrom();
|
||||
|
@ -421,6 +424,9 @@ class DefaultFetch
|
|||
*/
|
||||
bool interruptPending;
|
||||
|
||||
/** Is there a drain pending. */
|
||||
bool drainPending;
|
||||
|
||||
/** Records if fetch is switched out. */
|
||||
bool switchedOut;
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
|
|||
numThreads(params->numberOfThreads),
|
||||
numFetchingThreads(params->smtNumFetchingThreads),
|
||||
interruptPending(false),
|
||||
drainPending(false),
|
||||
switchedOut(false)
|
||||
{
|
||||
if (numThreads > Impl::MaxThreads)
|
||||
|
@ -353,7 +354,8 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
|
|||
// to return.
|
||||
if (fetchStatus[tid] != IcacheWaitResponse ||
|
||||
pkt->req != memReq[tid] ||
|
||||
isSwitchedOut()) {
|
||||
isSwitchedOut() ||
|
||||
drainPending) {
|
||||
++fetchIcacheSquashes;
|
||||
delete pkt->req;
|
||||
delete pkt;
|
||||
|
@ -384,17 +386,25 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
|
|||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultFetch<Impl>::switchOut()
|
||||
DefaultFetch<Impl>::drain()
|
||||
{
|
||||
// Fetch is ready to switch out at any time.
|
||||
switchedOut = true;
|
||||
cpu->signalSwitched();
|
||||
// Fetch is ready to drain at any time.
|
||||
cpu->signalDrained();
|
||||
drainPending = true;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultFetch<Impl>::doSwitchOut()
|
||||
DefaultFetch<Impl>::resume()
|
||||
{
|
||||
drainPending = false;
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultFetch<Impl>::switchOut()
|
||||
{
|
||||
switchedOut = true;
|
||||
// Branch predictor needs to have its state cleared.
|
||||
branchPred.switchOut();
|
||||
}
|
||||
|
@ -498,7 +508,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
|||
unsigned flags = 0;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
if (cacheBlocked || (interruptPending && flags == 0) || switchedOut) {
|
||||
if (cacheBlocked || (interruptPending && flags == 0) || drainPending) {
|
||||
// Hold off fetch from getting new instructions when:
|
||||
// Cache is blocked, or
|
||||
// while an interrupt is pending and we're not in PAL mode, or
|
||||
|
|
|
@ -143,11 +143,14 @@ class DefaultIEW
|
|||
/** Sets pointer to the scoreboard. */
|
||||
void setScoreboard(Scoreboard *sb_ptr);
|
||||
|
||||
/** Starts switch out of IEW stage. */
|
||||
void switchOut();
|
||||
/** Drains IEW stage. */
|
||||
void drain();
|
||||
|
||||
/** Resumes execution after a drain. */
|
||||
void resume();
|
||||
|
||||
/** Completes switch out of IEW stage. */
|
||||
void doSwitchOut();
|
||||
void switchOut();
|
||||
|
||||
/** Takes over from another CPU's thread. */
|
||||
void takeOverFrom();
|
||||
|
|
|
@ -355,15 +355,21 @@ DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
|
|||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultIEW<Impl>::switchOut()
|
||||
DefaultIEW<Impl>::drain()
|
||||
{
|
||||
// IEW is ready to switch out at any time.
|
||||
cpu->signalSwitched();
|
||||
// IEW is ready to drain at any time.
|
||||
cpu->signalDrained();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultIEW<Impl>::doSwitchOut()
|
||||
DefaultIEW<Impl>::resume()
|
||||
{
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultIEW<Impl>::switchOut()
|
||||
{
|
||||
// Clear any state.
|
||||
switchedOut = true;
|
||||
|
|
|
@ -157,12 +157,15 @@ class DefaultRename
|
|||
/** Sets pointer to the scoreboard. */
|
||||
void setScoreboard(Scoreboard *_scoreboard);
|
||||
|
||||
/** Drains the rename stage. */
|
||||
void drain();
|
||||
|
||||
/** Resumes execution after a drain. */
|
||||
void resume() { }
|
||||
|
||||
/** Switches out the rename stage. */
|
||||
void switchOut();
|
||||
|
||||
/** Completes the switch out. */
|
||||
void doSwitchOut();
|
||||
|
||||
/** Takes over from another CPU's thread. */
|
||||
void takeOverFrom();
|
||||
|
||||
|
|
|
@ -258,15 +258,15 @@ DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
|
|||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultRename<Impl>::switchOut()
|
||||
DefaultRename<Impl>::drain()
|
||||
{
|
||||
// Rename is ready to switch out at any time.
|
||||
cpu->signalSwitched();
|
||||
cpu->signalDrained();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void
|
||||
DefaultRename<Impl>::doSwitchOut()
|
||||
DefaultRename<Impl>::switchOut()
|
||||
{
|
||||
// Clear any state, fix up the rename map.
|
||||
for (int i = 0; i < numThreads; i++) {
|
||||
|
|
|
@ -547,7 +547,7 @@ class SimObject(object):
|
|||
count = 0
|
||||
# ParamContexts don't serialize
|
||||
if isinstance(self, SimObject) and not isinstance(self, ParamContext):
|
||||
if self._ccObject.drain(drain_event):
|
||||
if not self._ccObject.drain(drain_event):
|
||||
count = 1
|
||||
if recursive:
|
||||
for child in self._children.itervalues():
|
||||
|
|
|
@ -277,7 +277,7 @@ SimObject::drain(Event *drain_event)
|
|||
"in timing mode!");
|
||||
}
|
||||
state = DrainedAtomic;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -116,7 +116,7 @@ class SimObject : public Serializable, protected StartupCallback
|
|||
|
||||
// Methods to drain objects in order to take checkpoints
|
||||
// Or switch from timing -> atomic memory model
|
||||
// Quiesce returns true if the SimObject cannot quiesce immediately.
|
||||
// Drain returns false if the SimObject cannot drain immediately.
|
||||
virtual bool drain(Event *drain_event);
|
||||
virtual void resume();
|
||||
virtual void setMemoryMode(State new_mode);
|
||||
|
|
Loading…
Reference in a new issue