From 8ae4f45bc4782b4ab1dc95dbca183e2cd926fc5b Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 6 Jul 2006 16:06:00 -0400 Subject: Fixes for draining. src/cpu/simple/timing.cc: Update for changed return values. src/python/m5/__init__.py: Loop in order to make sure all objects are really drained. Objects may become undrained as other objects become drained (e.g. a bus-bridge has a packet, while a bus is empty, and the first drain() will cause the bus-bridge to give the packet to the bus). The only case we know every object is actually drained is if they all return immediately that they are drained. --HG-- extra : convert_revision : 80057a1d6d30381bd0b67b23549bd202f447c5cb --- src/cpu/simple/timing.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index ad04c8d3b..523d81d0b 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -118,11 +118,11 @@ TimingSimpleCPU::drain(Event *drain_event) // an access to complete. if (status() == Idle || status() == Running || status() == SwitchedOut) { changeState(SimObject::DrainedTiming); - return false; + return true; } else { changeState(SimObject::Draining); drainEvent = drain_event; - return true; + return false; } } -- cgit v1.2.3 From e7ccc94ea3cdc6130e66899fd905ca11da958727 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 6 Jul 2006 17:53:26 -0400 Subject: Various serialization changes to make it possible for the O3CPU to checkpoint. src/arch/alpha/regfile.hh: Define serialize/unserialize functions on MiscRegFile itself. src/cpu/o3/regfile.hh: Remove old commented code. src/cpu/simple_thread.cc: src/cpu/simple_thread.hh: Push common serialization code to ThreadState level. Also allow the SimpleThread to be used for checkpointing by other models. src/cpu/thread_state.cc: src/cpu/thread_state.hh: Move common serialization code into ThreadState. --HG-- extra : convert_revision : ef64ef515355437439af967eda2e610e8c1b658b --- src/cpu/o3/regfile.hh | 4 --- src/cpu/simple_thread.cc | 72 +++++++++++++++++++++++++----------------------- src/cpu/simple_thread.hh | 8 ++++-- src/cpu/thread_state.cc | 43 +++++++++++++++++++++++++++++ src/cpu/thread_state.hh | 6 ++++ 5 files changed, 91 insertions(+), 42 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index 6972f055f..b6677b4b1 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -86,10 +86,6 @@ class PhysRegFile //The duplication is unfortunate but it's better than having //different ways to access certain registers. - //Add these in later when everything else is in place -// void serialize(std::ostream &os); -// void unserialize(Checkpoint *cp, const std::string §ion); - /** Reads an integer register. */ uint64_t readIntReg(PhysRegIndex reg_idx) { diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index db28b23e8..6255b3357 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -123,14 +123,31 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, tc = new ProxyThreadContext(this); } -SimpleThread::SimpleThread(RegFile *regFile) - : ThreadState(-1, -1, NULL, -1, NULL), cpu(NULL) +#endif + +SimpleThread::SimpleThread(ThreadContext *oldContext) +#if FULL_SYSTEM + : ThreadState(-1, -1) +#else + : ThreadState(-1, -1, NULL, -1, NULL) +#endif { - regs = *regFile; tc = new ProxyThreadContext(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() { @@ -147,13 +164,8 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext) assert(process == oldContext->getProcessPtr()); #endif - // copy over functional state - _status = oldContext->status(); - copyArchRegs(oldContext); - cpuId = oldContext->readCpuId(); -#if !FULL_SYSTEM - funcExeInst = oldContext->readFuncExeInst(); -#else + copyState(oldContext); +#if FULL_SYSTEM EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent(); if (quiesce) { // Point the quiesce event's TC at this TC so that it wakes up @@ -170,43 +182,33 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext) oldContext->setStatus(ThreadContext::Unallocated); } +void +SimpleThread::copyState(ThreadContext *oldContext) +{ + // copy over functional state + _status = oldContext->status(); + copyArchRegs(oldContext); + cpuId = oldContext->readCpuId(); +#if !FULL_SYSTEM + funcExeInst = oldContext->readFuncExeInst(); +#endif +} + void SimpleThread::serialize(ostream &os) { - SERIALIZE_ENUM(_status); + ThreadState::serialize(os); regs.serialize(os); // thread_num and cpu_id are deterministic from the config - SERIALIZE_SCALAR(funcExeInst); - SERIALIZE_SCALAR(inst); - -#if FULL_SYSTEM - Tick quiesceEndTick = 0; - if (quiesceEvent->scheduled()) - quiesceEndTick = quiesceEvent->when(); - SERIALIZE_SCALAR(quiesceEndTick); - if (kernelStats) - kernelStats->serialize(os); -#endif } void SimpleThread::unserialize(Checkpoint *cp, const std::string §ion) { - UNSERIALIZE_ENUM(_status); + ThreadState::unserialize(cp, section); regs.unserialize(cp, section); // thread_num and cpu_id are deterministic from the config - UNSERIALIZE_SCALAR(funcExeInst); - UNSERIALIZE_SCALAR(inst); - -#if FULL_SYSTEM - Tick quiesceEndTick; - UNSERIALIZE_SCALAR(quiesceEndTick); - if (quiesceEndTick) - quiesceEvent->schedule(quiesceEndTick); - if (kernelStats) - kernelStats->unserialize(cp, section); -#endif } #if FULL_SYSTEM diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index de65e9891..ff2639e10 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -119,16 +119,18 @@ class SimpleThread : public ThreadState #else SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, MemObject *memobj); - // Constructor to use SimpleThread to pass reg file around. Not - // used for anything else. - SimpleThread(RegFile *regFile); #endif + + SimpleThread(ThreadContext *oldContext); + virtual ~SimpleThread(); virtual void takeOverFrom(ThreadContext *oldContext); void regStats(const std::string &name); + void copyState(ThreadContext *oldContext); + void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index 872678a41..6a96560f1 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -31,6 +31,12 @@ #include "base/output.hh" #include "cpu/profile.hh" #include "cpu/thread_state.hh" +#include "sim/serialize.hh" + +#if FULL_SYSTEM +#include "cpu/quiesce_event.hh" +#include "kern/kernel_stats.hh" +#endif #if FULL_SYSTEM ThreadState::ThreadState(int _cpuId, int _tid) @@ -49,6 +55,43 @@ ThreadState::ThreadState(int _cpuId, int _tid, Process *_process, numLoad = 0; } +void +ThreadState::serialize(std::ostream &os) +{ + SERIALIZE_ENUM(_status); + // thread_num and cpu_id are deterministic from the config + SERIALIZE_SCALAR(funcExeInst); + SERIALIZE_SCALAR(inst); + +#if FULL_SYSTEM + Tick quiesceEndTick = 0; + if (quiesceEvent->scheduled()) + quiesceEndTick = quiesceEvent->when(); + SERIALIZE_SCALAR(quiesceEndTick); + if (kernelStats) + kernelStats->serialize(os); +#endif +} + +void +ThreadState::unserialize(Checkpoint *cp, const std::string §ion) +{ + + UNSERIALIZE_ENUM(_status); + // thread_num and cpu_id are deterministic from the config + UNSERIALIZE_SCALAR(funcExeInst); + UNSERIALIZE_SCALAR(inst); + +#if FULL_SYSTEM + Tick quiesceEndTick; + UNSERIALIZE_SCALAR(quiesceEndTick); + if (quiesceEndTick) + quiesceEvent->schedule(quiesceEndTick); + if (kernelStats) + kernelStats->unserialize(cp, section); +#endif +} + #if FULL_SYSTEM void diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index cb1449ac5..b03a2e2bb 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -49,6 +49,8 @@ namespace Kernel { }; #endif +class Checkpoint; + /** * Struct for holding general thread state that is needed across CPU * models. This includes things such as pointers to the process, @@ -65,6 +67,10 @@ struct ThreadState { short _asid, MemObject *mem); #endif + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + void setCpuId(int id) { cpuId = id; } int readCpuId() { return cpuId; } -- cgit v1.2.3 From fbe3e22474184e537fe74f4e86277056026f0514 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 6 Jul 2006 17:57:20 -0400 Subject: 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 --- src/cpu/o3/commit.hh | 2 +- src/cpu/o3/commit_impl.hh | 10 +++++++++- src/cpu/o3/cpu.cc | 25 +++++++++++++++++++------ src/cpu/o3/decode.hh | 2 +- src/cpu/o3/decode_impl.hh | 3 ++- src/cpu/o3/fetch.hh | 2 +- src/cpu/o3/fetch_impl.hh | 3 ++- src/cpu/o3/iew.hh | 2 +- src/cpu/o3/iew_impl.hh | 3 ++- src/cpu/o3/rename.hh | 2 +- src/cpu/o3/rename_impl.hh | 3 ++- 11 files changed, 41 insertions(+), 16 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh index 49ff5cdad..c39bc10f9 100644 --- a/src/cpu/o3/commit.hh +++ b/src/cpu/o3/commit.hh @@ -188,7 +188,7 @@ class DefaultCommit void initStage(); /** Initializes the draining of commit. */ - void drain(); + bool drain(); /** Resumes execution after draining. */ void resume(); diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 2eb05afac..b50c9a898 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -350,10 +350,18 @@ DefaultCommit::initStage() } template -void +bool DefaultCommit::drain() { drainPending = true; + + // If it's already drained, return true. + if (rob->isEmpty() && !iewStage->hasStoresToWB()) { + cpu->signalDrained(); + return true; + } + + return false; } template diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index b182d5ca7..3a52fe4c2 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -712,19 +712,27 @@ bool FullO3CPU::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 @@ -751,8 +759,13 @@ FullO3CPU::signalDrained() if (++drainCount == NumStages) { if (tickEvent.scheduled()) tickEvent.squash(); + _status = Drained; - drainEvent->process(); + + if (drainEvent) { + drainEvent->process(); + drainEvent = NULL; + } } assert(drainCount <= 5); } diff --git a/src/cpu/o3/decode.hh b/src/cpu/o3/decode.hh index 1e96f1884..7f5ecbc26 100644 --- a/src/cpu/o3/decode.hh +++ b/src/cpu/o3/decode.hh @@ -110,7 +110,7 @@ class DefaultDecode void setActiveThreads(std::list *at_ptr); /** Drains the decode stage. */ - void drain(); + bool drain(); /** Resumes execution after a drain. */ void resume() { } diff --git a/src/cpu/o3/decode_impl.hh b/src/cpu/o3/decode_impl.hh index 71637883b..8b851c032 100644 --- a/src/cpu/o3/decode_impl.hh +++ b/src/cpu/o3/decode_impl.hh @@ -165,11 +165,12 @@ DefaultDecode::setActiveThreads(list *at_ptr) } template -void +bool DefaultDecode::drain() { // Decode is done draining at any time. cpu->signalDrained(); + return true; } template diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 9611f0455..a793c7361 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -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(); diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 500b5304e..c0cc189f2 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -385,12 +385,13 @@ DefaultFetch::processCacheCompletion(PacketPtr pkt) } template -void +bool DefaultFetch::drain() { // Fetch is ready to drain at any time. cpu->signalDrained(); drainPending = true; + return true; } template diff --git a/src/cpu/o3/iew.hh b/src/cpu/o3/iew.hh index 774b6dcbd..4908a6649 100644 --- a/src/cpu/o3/iew.hh +++ b/src/cpu/o3/iew.hh @@ -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(); diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index c3aa748ae..0d82645e3 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -354,11 +354,12 @@ DefaultIEW::setScoreboard(Scoreboard *sb_ptr) } template -void +bool DefaultIEW::drain() { // IEW is ready to drain at any time. cpu->signalDrained(); + return true; } template diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index 538dd9bb4..034087feb 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -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() { } diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index fddbae3db..805a72808 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -257,11 +257,12 @@ DefaultRename::setScoreboard(Scoreboard *_scoreboard) } template -void +bool DefaultRename::drain() { // Rename is ready to switch out at any time. cpu->signalDrained(); + return true; } template -- cgit v1.2.3 From fff75316771331ec3247cbd6e424a93b252a1e29 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 6 Jul 2006 23:13:38 -0400 Subject: 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 --- src/cpu/o3/commit_impl.hh | 1 + src/cpu/o3/cpu.cc | 61 ++++++++++++++++++++++++++++++++++++++++------- src/cpu/o3/cpu.hh | 8 ++++++- src/cpu/o3/lsq_impl.hh | 3 +++ src/cpu/simple_thread.cc | 32 ++++++++++++++----------- src/cpu/simple_thread.hh | 4 +++- 6 files changed, 84 insertions(+), 25 deletions(-) (limited to 'src/cpu') 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 void DefaultCommit::resume() { + drainPending = false; } template 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 @@ -707,6 +707,47 @@ FullO3CPU::haltContext(int tid) */ } +template +void +FullO3CPU::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 +void +FullO3CPU::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 bool FullO3CPU::drain(Event *drain_event) @@ -717,15 +758,16 @@ FullO3CPU::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 void FullO3CPU::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::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::hasStoresToWB() { list::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(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() @@ -182,6 +169,23 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext) oldContext->setStatus(ThreadContext::Unallocated); } +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) { 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); -- cgit v1.2.3