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
This commit is contained in:
Kevin Lim 2006-07-06 17:53:26 -04:00
parent 8bf9709d91
commit e7ccc94ea3
6 changed files with 98 additions and 45 deletions

View file

@ -112,6 +112,10 @@ namespace AlphaISA
lock_flag = 0;
lock_addr = 0;
}
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
#if FULL_SYSTEM
protected:
typedef uint64_t InternalProcReg;

View file

@ -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 &section);
/** Reads an integer register. */
uint64_t readIntReg(PhysRegIndex reg_idx)
{

View file

@ -123,15 +123,32 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
tc = new ProxyThreadContext<SimpleThread>(this);
}
SimpleThread::SimpleThread(RegFile *regFile)
: ThreadState(-1, -1, NULL, -1, NULL), cpu(NULL)
{
regs = *regFile;
tc = new ProxyThreadContext<SimpleThread>(this);
}
#endif
SimpleThread::SimpleThread(ThreadContext *oldContext)
#if FULL_SYSTEM
: ThreadState(-1, -1)
#else
: ThreadState(-1, -1, NULL, -1, NULL)
#endif
{
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()
{
delete tc;
@ -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 &section)
{
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

View file

@ -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 &section);

View file

@ -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 &section)
{
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

View file

@ -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 &section);
void setCpuId(int id) { cpuId = id; }
int readCpuId() { return cpuId; }