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:
parent
8bf9709d91
commit
e7ccc94ea3
6 changed files with 98 additions and 45 deletions
|
@ -112,6 +112,10 @@ namespace AlphaISA
|
|||
lock_flag = 0;
|
||||
lock_addr = 0;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
#if FULL_SYSTEM
|
||||
protected:
|
||||
typedef uint64_t InternalProcReg;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 §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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in a new issue