diff options
author | Kevin Lim <ktlim@umich.edu> | 2006-07-06 23:13:38 -0400 |
---|---|---|
committer | Kevin Lim <ktlim@umich.edu> | 2006-07-06 23:13:38 -0400 |
commit | fff75316771331ec3247cbd6e424a93b252a1e29 (patch) | |
tree | 0e2e96841ebd160ef0160dd3dc56aa0a56696b86 /src/cpu | |
parent | fbe3e22474184e537fe74f4e86277056026f0514 (diff) | |
download | gem5-fff75316771331ec3247cbd6e424a93b252a1e29.tar.xz |
Support serializing and unserializing in the O3 CPU. Also a few small fixes for draining/switching CPUs.
src/cpu/o3/commit_impl.hh:
Fix to clear drainPending variable on call to resume.
src/cpu/o3/cpu.cc:
src/cpu/o3/cpu.hh:
Support serializing and unserializing in the O3 CPU.
src/cpu/o3/lsq_impl.hh:
Be sure to say we have no stores to write back if the active thread list is empty.
src/cpu/simple_thread.cc:
src/cpu/simple_thread.hh:
Slightly change how SimpleThread is used to copy from other ThreadContexts.
--HG--
extra : convert_revision : 92a5109b3783a989d5b451036061ef82c56d3121
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 1 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 61 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 8 | ||||
-rw-r--r-- | src/cpu/o3/lsq_impl.hh | 3 | ||||
-rw-r--r-- | src/cpu/simple_thread.cc | 32 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh | 4 |
6 files changed, 84 insertions, 25 deletions
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index b50c9a898..39e1cf3fe 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -377,6 +377,7 @@ template <class Impl> void DefaultCommit<Impl>::resume() { + drainPending = false; } template <class Impl> diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 3a52fe4c2..f345fe82d 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -708,6 +708,47 @@ FullO3CPU<Impl>::haltContext(int tid) } template <class Impl> +void +FullO3CPU<Impl>::serialize(std::ostream &os) +{ + SERIALIZE_ENUM(_status); + BaseCPU::serialize(os); + nameOut(os, csprintf("%s.tickEvent", name())); + tickEvent.serialize(os); + + // Use SimpleThread's ability to checkpoint to make it easier to + // write out the registers. Also make this static so it doesn't + // get instantiated multiple times (causes a panic in statistics). + static SimpleThread temp; + + for (int i = 0; i < thread.size(); i++) { + nameOut(os, csprintf("%s.xc.%i", name(), i)); + temp.copyTC(thread[i]->getTC()); + temp.serialize(os); + } +} + +template <class Impl> +void +FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ENUM(_status); + BaseCPU::unserialize(cp, section); + tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); + + // Use SimpleThread's ability to checkpoint to make it easier to + // read in the registers. Also make this static so it doesn't + // get instantiated multiple times (causes a panic in statistics). + static SimpleThread temp; + + for (int i = 0; i < thread.size(); i++) { + temp.copyTC(thread[i]->getTC()); + temp.unserialize(cp, csprintf("%s.xc.%i", section, i)); + thread[i]->getTC()->copyArchRegs(temp.getTC()); + } +} + +template <class Impl> bool FullO3CPU<Impl>::drain(Event *drain_event) { @@ -717,15 +758,16 @@ FullO3CPU<Impl>::drain(Event *drain_event) 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 was not able to immediately drain. - if (_status != Drained) { + if (getState() != SimObject::DrainedTiming) { + // 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; + wakeCPU(); activityRec.activity(); @@ -739,14 +781,15 @@ template <class Impl> void FullO3CPU<Impl>::resume() { - if (_status == SwitchedOut) - return; fetch.resume(); decode.resume(); rename.resume(); iew.resume(); commit.resume(); + if (_status == SwitchedOut || _status == Idle) + return; + if (!tickEvent.scheduled()) tickEvent.schedule(curTick); _status = Running; @@ -760,7 +803,7 @@ FullO3CPU<Impl>::signalDrained() if (tickEvent.scheduled()) tickEvent.squash(); - _status = Drained; + changeState(SimObject::DrainedTiming); if (drainEvent) { drainEvent->process(); diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index cf3747601..5b881e558 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -111,7 +111,6 @@ class FullO3CPU : public BaseO3CPU Idle, Halted, Blocked, - Drained, SwitchedOut }; @@ -266,6 +265,13 @@ class FullO3CPU : public BaseO3CPU /** Update The Order In Which We Process Threads. */ void updateThreadPriority(); + /** Serialize state. */ + virtual void serialize(std::ostream &os); + + /** Unserialize from a checkpoint. */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); + + public: /** Executes a syscall on this cycle. * --------------------------------------- * Note: this is a virtual function. CPU-Specific diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh index 5173f8be1..89fd1a71d 100644 --- a/src/cpu/o3/lsq_impl.hh +++ b/src/cpu/o3/lsq_impl.hh @@ -502,6 +502,9 @@ LSQ<Impl>::hasStoresToWB() { list<unsigned>::iterator active_threads = (*activeThreads).begin(); + if ((*activeThreads).empty()) + return false; + while (active_threads != (*activeThreads).end()) { unsigned tid = *active_threads++; if (!hasStoresToWB(tid)) diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 6255b3357..af1db2ff2 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -125,7 +125,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, #endif -SimpleThread::SimpleThread(ThreadContext *oldContext) +SimpleThread::SimpleThread() #if FULL_SYSTEM : ThreadState(-1, -1) #else @@ -134,19 +134,6 @@ SimpleThread::SimpleThread(ThreadContext *oldContext) { tc = new ProxyThreadContext<SimpleThread>(this); regs.clear(); - - copyState(oldContext); - -#if FULL_SYSTEM - EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent(); - if (quiesce) { - quiesceEvent = quiesce; - } - Kernel::Statistics *stats = oldContext->getKernelStats(); - if (stats) { - kernelStats = stats; - } -#endif } SimpleThread::~SimpleThread() @@ -183,6 +170,23 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext) } void +SimpleThread::copyTC(ThreadContext *context) +{ + copyState(context); + +#if FULL_SYSTEM + EndQuiesceEvent *quiesce = context->getQuiesceEvent(); + if (quiesce) { + quiesceEvent = quiesce; + } + Kernel::Statistics *stats = context->getKernelStats(); + if (stats) { + kernelStats = stats; + } +#endif +} + +void SimpleThread::copyState(ThreadContext *oldContext) { // copy over functional state diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index ff2639e10..d36853db4 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -121,7 +121,7 @@ class SimpleThread : public ThreadState MemObject *memobj); #endif - SimpleThread(ThreadContext *oldContext); + SimpleThread(); virtual ~SimpleThread(); @@ -129,6 +129,8 @@ class SimpleThread : public ThreadState void regStats(const std::string &name); + void copyTC(ThreadContext *context); + void copyState(ThreadContext *oldContext); void serialize(std::ostream &os); |