sim: revamp unserialization procedure
Replace direct call to unserialize() on each SimObject with a pair of calls for better control over initialization in both ckpt and non-ckpt cases. If restoring from a checkpoint, loadState(ckpt) is called on each SimObject. The default implementation simply calls unserialize() if there is a corresponding checkpoint section, so we get backward compatibility for existing objects. However, objects can override loadState() to get other behaviors, e.g., doing other programmed initializations after unserialize(), or complaining if no checkpoint section is found. (Note that the default warning for a missing checkpoint section is now gone.) If not restoring from a checkpoint, we call the new initState() method on each SimObject instead. This provides a hook for state initializations that are only required when *not* restoring from a checkpoint. Given this new framework, do some cleanup of LiveProcess subclasses and X86System, which were (in some cases) emulating initState() behavior in startup via a local flag or (in other cases) erroneously doing initializations in startup() that clobbered state loaded earlier by unserialize().
This commit is contained in:
parent
2519d116c9
commit
f064aa3060
|
@ -173,19 +173,35 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AlphaLiveProcess::startup()
|
AlphaLiveProcess::setupASNReg()
|
||||||
{
|
{
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
|
tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
|
||||||
|
|
||||||
if (checkpointRestored) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::startup();
|
|
||||||
|
void
|
||||||
|
AlphaLiveProcess::loadState(Checkpoint *cp)
|
||||||
|
{
|
||||||
|
LiveProcess::loadState(cp);
|
||||||
|
// need to set up ASN after unserialization since M5_pid value may
|
||||||
|
// come from checkpoint
|
||||||
|
setupASNReg();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AlphaLiveProcess::initState()
|
||||||
|
{
|
||||||
|
// need to set up ASN before further initialization since init
|
||||||
|
// will involve writing to virtual memory addresses
|
||||||
|
setupASNReg();
|
||||||
|
|
||||||
|
LiveProcess::initState();
|
||||||
|
|
||||||
argsInit(MachineBytes, VMPageSize);
|
argsInit(MachineBytes, VMPageSize);
|
||||||
|
|
||||||
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
tc->setIntReg(GlobalPointerReg, objFile->globalPointer());
|
tc->setIntReg(GlobalPointerReg, objFile->globalPointer());
|
||||||
//Operate in user mode
|
//Operate in user mode
|
||||||
tc->setMiscRegNoEffect(IPR_ICM, 0x18);
|
tc->setMiscRegNoEffect(IPR_ICM, 0x18);
|
||||||
|
|
|
@ -36,10 +36,14 @@
|
||||||
|
|
||||||
class AlphaLiveProcess : public LiveProcess
|
class AlphaLiveProcess : public LiveProcess
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
void setupASNReg();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile);
|
AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile);
|
||||||
|
|
||||||
void startup();
|
void loadState(Checkpoint *cp);
|
||||||
|
void initState();
|
||||||
|
|
||||||
void argsInit(int intSize, int pageSize);
|
void argsInit(int intSize, int pageSize);
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ ArmLiveProcess::ArmLiveProcess(LiveProcessParams *params, ObjectFile *objFile,
|
||||||
void
|
void
|
||||||
ArmLiveProcess::startup()
|
ArmLiveProcess::startup()
|
||||||
{
|
{
|
||||||
|
LiveProcess::startup();
|
||||||
argsInit(MachineBytes, VMPageSize);
|
argsInit(MachineBytes, VMPageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,9 +115,6 @@ ArmLiveProcess::argsInit(int intSize, int pageSize)
|
||||||
//We want 16 byte alignment
|
//We want 16 byte alignment
|
||||||
uint64_t align = 16;
|
uint64_t align = 16;
|
||||||
|
|
||||||
// Overloaded argsInit so that we can fine-tune for ARM architecture
|
|
||||||
Process::startup();
|
|
||||||
|
|
||||||
// load object file into target memory
|
// load object file into target memory
|
||||||
objFile->loadSections(initVirtMem);
|
objFile->loadSections(initVirtMem);
|
||||||
|
|
||||||
|
|
|
@ -67,9 +67,9 @@ MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MipsLiveProcess::startup()
|
MipsLiveProcess::initState()
|
||||||
{
|
{
|
||||||
Process::startup();
|
LiveProcess::initState();
|
||||||
|
|
||||||
argsInit<uint32_t>(VMPageSize);
|
argsInit<uint32_t>(VMPageSize);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,6 @@ void
|
||||||
MipsLiveProcess::argsInit(int pageSize)
|
MipsLiveProcess::argsInit(int pageSize)
|
||||||
{
|
{
|
||||||
int intSize = sizeof(IntType);
|
int intSize = sizeof(IntType);
|
||||||
Process::startup();
|
|
||||||
|
|
||||||
// load object file into target memory
|
// load object file into target memory
|
||||||
objFile->loadSections(initVirtMem);
|
objFile->loadSections(initVirtMem);
|
||||||
|
|
|
@ -45,7 +45,7 @@ class MipsLiveProcess : public LiveProcess
|
||||||
protected:
|
protected:
|
||||||
MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
|
MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
|
||||||
|
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
template<class IntType>
|
template<class IntType>
|
||||||
void argsInit(int pageSize);
|
void argsInit(int pageSize);
|
||||||
|
|
|
@ -432,9 +432,9 @@ PowerLinuxProcess::getDesc(int callnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PowerLinuxProcess::startup()
|
PowerLinuxProcess::initState()
|
||||||
{
|
{
|
||||||
PowerLiveProcess::startup();
|
PowerLiveProcess::initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
PowerISA::IntReg
|
PowerISA::IntReg
|
||||||
|
|
|
@ -44,7 +44,7 @@ class PowerLinuxProcess : public PowerLiveProcess
|
||||||
|
|
||||||
virtual SyscallDesc* getDesc(int callnum);
|
virtual SyscallDesc* getDesc(int callnum);
|
||||||
|
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
||||||
void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val);
|
void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val);
|
||||||
|
|
|
@ -63,8 +63,10 @@ PowerLiveProcess::PowerLiveProcess(LiveProcessParams *params,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PowerLiveProcess::startup()
|
PowerLiveProcess::initState()
|
||||||
{
|
{
|
||||||
|
Process::initState();
|
||||||
|
|
||||||
argsInit(MachineBytes, VMPageSize);
|
argsInit(MachineBytes, VMPageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,9 +85,6 @@ PowerLiveProcess::argsInit(int intSize, int pageSize)
|
||||||
//We want 16 byte alignment
|
//We want 16 byte alignment
|
||||||
uint64_t align = 16;
|
uint64_t align = 16;
|
||||||
|
|
||||||
// Overloaded argsInit so that we can fine-tune for POWER architecture
|
|
||||||
Process::startup();
|
|
||||||
|
|
||||||
// load object file into target memory
|
// load object file into target memory
|
||||||
objFile->loadSections(initVirtMem);
|
objFile->loadSections(initVirtMem);
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class PowerLiveProcess : public LiveProcess
|
||||||
protected:
|
protected:
|
||||||
PowerLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
|
PowerLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
|
||||||
|
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void argsInit(int intSize, int pageSize);
|
void argsInit(int intSize, int pageSize);
|
||||||
|
|
|
@ -111,9 +111,9 @@ void SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SparcLiveProcess::startup()
|
SparcLiveProcess::initState()
|
||||||
{
|
{
|
||||||
Process::startup();
|
LiveProcess::initState();
|
||||||
|
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
//From the SPARC ABI
|
//From the SPARC ABI
|
||||||
|
@ -157,12 +157,9 @@ SparcLiveProcess::startup()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sparc32LiveProcess::startup()
|
Sparc32LiveProcess::initState()
|
||||||
{
|
{
|
||||||
if (checkpointRestored)
|
SparcLiveProcess::initState();
|
||||||
return;
|
|
||||||
|
|
||||||
SparcLiveProcess::startup();
|
|
||||||
|
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
//The process runs in user mode with 32 bit addresses
|
//The process runs in user mode with 32 bit addresses
|
||||||
|
@ -172,12 +169,9 @@ Sparc32LiveProcess::startup()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sparc64LiveProcess::startup()
|
Sparc64LiveProcess::initState()
|
||||||
{
|
{
|
||||||
if (checkpointRestored)
|
SparcLiveProcess::initState();
|
||||||
return;
|
|
||||||
|
|
||||||
SparcLiveProcess::startup();
|
|
||||||
|
|
||||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||||
//The process runs in user mode
|
//The process runs in user mode
|
||||||
|
|
|
@ -52,7 +52,7 @@ class SparcLiveProcess : public LiveProcess
|
||||||
SparcLiveProcess(LiveProcessParams * params,
|
SparcLiveProcess(LiveProcessParams * params,
|
||||||
ObjectFile *objFile, Addr _StackBias);
|
ObjectFile *objFile, Addr _StackBias);
|
||||||
|
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
template<class IntType>
|
template<class IntType>
|
||||||
void argsInit(int pageSize);
|
void argsInit(int pageSize);
|
||||||
|
@ -87,7 +87,7 @@ class Sparc32LiveProcess : public SparcLiveProcess
|
||||||
mmap_start = mmap_end = 0x70000000;
|
mmap_start = mmap_end = 0x70000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ class Sparc64LiveProcess : public SparcLiveProcess
|
||||||
mmap_start = mmap_end = 0xfffff80000000000ULL;
|
mmap_start = mmap_end = 0xfffff80000000000ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,9 @@ LinuxX86System::~LinuxX86System()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LinuxX86System::startup()
|
LinuxX86System::initState()
|
||||||
{
|
{
|
||||||
X86System::startup();
|
X86System::initState();
|
||||||
|
|
||||||
// The location of the real mode data structure.
|
// The location of the real mode data structure.
|
||||||
const Addr realModeData = 0x90200;
|
const Addr realModeData = 0x90200;
|
||||||
|
|
|
@ -58,7 +58,7 @@ class LinuxX86System : public X86System
|
||||||
LinuxX86System(Params *p);
|
LinuxX86System(Params *p);
|
||||||
~LinuxX86System();
|
~LinuxX86System();
|
||||||
|
|
||||||
void startup();
|
void initState();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -157,12 +157,9 @@ X86LiveProcess::getDesc(int callnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86_64LiveProcess::startup()
|
X86_64LiveProcess::initState()
|
||||||
{
|
{
|
||||||
LiveProcess::startup();
|
X86LiveProcess::initState();
|
||||||
|
|
||||||
if (checkpointRestored)
|
|
||||||
return;
|
|
||||||
|
|
||||||
argsInit(sizeof(uint64_t), VMPageSize);
|
argsInit(sizeof(uint64_t), VMPageSize);
|
||||||
|
|
||||||
|
@ -255,12 +252,9 @@ X86_64LiveProcess::startup()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
I386LiveProcess::startup()
|
I386LiveProcess::initState()
|
||||||
{
|
{
|
||||||
LiveProcess::startup();
|
X86LiveProcess::initState();
|
||||||
|
|
||||||
if (checkpointRestored)
|
|
||||||
return;
|
|
||||||
|
|
||||||
argsInit(sizeof(uint32_t), VMPageSize);
|
argsInit(sizeof(uint32_t), VMPageSize);
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ namespace X86ISA
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void argsInit(int intSize, int pageSize);
|
void argsInit(int intSize, int pageSize);
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
||||||
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
|
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
|
||||||
|
@ -123,7 +123,7 @@ namespace X86ISA
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void argsInit(int intSize, int pageSize);
|
void argsInit(int intSize, int pageSize);
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
void syscall(int64_t callnum, ThreadContext *tc);
|
void syscall(int64_t callnum, ThreadContext *tc);
|
||||||
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
|
||||||
|
|
|
@ -109,9 +109,10 @@ installSegDesc(ThreadContext *tc, SegmentRegIndex seg,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86System::startup()
|
X86System::initState()
|
||||||
{
|
{
|
||||||
System::startup();
|
System::initState();
|
||||||
|
|
||||||
ThreadContext *tc = threadContexts[0];
|
ThreadContext *tc = threadContexts[0];
|
||||||
// This is the boot strap processor (BSP). Initialize it to look like
|
// This is the boot strap processor (BSP). Initialize it to look like
|
||||||
// the boot loader has just turned control over to the 64 bit OS. We
|
// the boot loader has just turned control over to the 64 bit OS. We
|
||||||
|
|
|
@ -77,7 +77,7 @@ class X86System : public System
|
||||||
void serialize(std::ostream &os);
|
void serialize(std::ostream &os);
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
void startup();
|
void initState();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,12 @@ def instantiate(ckpt_dir=None):
|
||||||
|
|
||||||
# Restore checkpoint (if any)
|
# Restore checkpoint (if any)
|
||||||
if ckpt_dir:
|
if ckpt_dir:
|
||||||
internal.core.unserializeAll(ckpt_dir)
|
ckpt = internal.core.getCheckpoint(ckpt_dir)
|
||||||
|
internal.core.unserializeGlobals(ckpt);
|
||||||
|
for obj in root.descendants(): obj.loadState(ckpt)
|
||||||
need_resume.append(root)
|
need_resume.append(root)
|
||||||
|
else:
|
||||||
|
for obj in root.descendants(): obj.initState()
|
||||||
|
|
||||||
# Reset to put the stats in a consistent state.
|
# Reset to put the stats in a consistent state.
|
||||||
stats.reset()
|
stats.reset()
|
||||||
|
|
|
@ -75,8 +75,11 @@ void setClockFrequency(Tick ticksPerSecond);
|
||||||
%immutable curTick;
|
%immutable curTick;
|
||||||
Tick curTick;
|
Tick curTick;
|
||||||
|
|
||||||
|
class Checkpoint;
|
||||||
|
|
||||||
void serializeAll(const std::string &cpt_dir);
|
void serializeAll(const std::string &cpt_dir);
|
||||||
void unserializeAll(const std::string &cpt_dir);
|
Checkpoint *getCheckpoint(const std::string &cpt_dir);
|
||||||
|
void unserializeGlobals(Checkpoint *cp);
|
||||||
|
|
||||||
bool want_warn, warn_verbose;
|
bool want_warn, warn_verbose;
|
||||||
bool want_info, info_verbose;
|
bool want_info, info_verbose;
|
||||||
|
|
|
@ -52,8 +52,14 @@ serializeAll(const std::string &cpt_dir)
|
||||||
Serializable::serializeAll(cpt_dir);
|
Serializable::serializeAll(cpt_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline Checkpoint *
|
||||||
unserializeAll(const std::string &cpt_dir)
|
getCheckpoint(const std::string &cpt_dir)
|
||||||
{
|
{
|
||||||
Serializable::unserializeAll(cpt_dir);
|
return new Checkpoint(cpt_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
unserializeGlobals(Checkpoint *cp)
|
||||||
|
{
|
||||||
|
Serializable::unserializeGlobals(cp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ class SimObject {
|
||||||
};
|
};
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
void loadState(Checkpoint *cp);
|
||||||
|
void initState();
|
||||||
void regStats();
|
void regStats();
|
||||||
void regFormulas();
|
void regFormulas();
|
||||||
void resetStats();
|
void resetStats();
|
||||||
|
|
|
@ -100,7 +100,7 @@ template class AuxVector<uint32_t>;
|
||||||
template class AuxVector<uint64_t>;
|
template class AuxVector<uint64_t>;
|
||||||
|
|
||||||
Process::Process(ProcessParams * params)
|
Process::Process(ProcessParams * params)
|
||||||
: SimObject(params), system(params->system), checkpointRestored(false),
|
: SimObject(params), system(params->system),
|
||||||
max_stack_size(params->max_stack_size)
|
max_stack_size(params->max_stack_size)
|
||||||
{
|
{
|
||||||
string in = params->input;
|
string in = params->input;
|
||||||
|
@ -233,7 +233,7 @@ Process::findFreeContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Process::startup()
|
Process::initState()
|
||||||
{
|
{
|
||||||
if (contextIds.empty())
|
if (contextIds.empty())
|
||||||
fatal("Process %s is not associated with any HW contexts!\n", name());
|
fatal("Process %s is not associated with any HW contexts!\n", name());
|
||||||
|
@ -537,9 +537,6 @@ Process::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
// find the param in the checkpoint if you wanted to, like set a default
|
// find the param in the checkpoint if you wanted to, like set a default
|
||||||
// but in this case we'll just stick with the instantianted value if not
|
// but in this case we'll just stick with the instantianted value if not
|
||||||
// found.
|
// found.
|
||||||
|
|
||||||
checkpointRestored = true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,6 @@ class Process : public SimObject
|
||||||
/// running on.
|
/// running on.
|
||||||
System *system;
|
System *system;
|
||||||
|
|
||||||
bool checkpointRestored;
|
|
||||||
|
|
||||||
// thread contexts associated with this process
|
// thread contexts associated with this process
|
||||||
std::vector<int> contextIds;
|
std::vector<int> contextIds;
|
||||||
|
|
||||||
|
@ -130,8 +128,7 @@ class Process : public SimObject
|
||||||
// constructor
|
// constructor
|
||||||
Process(ProcessParams * params);
|
Process(ProcessParams * params);
|
||||||
|
|
||||||
// post initialization startup
|
virtual void initState();
|
||||||
virtual void startup();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Memory object for initialization (image loading)
|
/// Memory object for initialization (image loading)
|
||||||
|
|
|
@ -451,17 +451,6 @@ Serializable::serializeAll(const string &cpt_dir)
|
||||||
SimObject::serializeAll(outstream);
|
SimObject::serializeAll(outstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Serializable::unserializeAll(const string &cpt_dir)
|
|
||||||
{
|
|
||||||
string dir = Checkpoint::setDir(cpt_dir);
|
|
||||||
|
|
||||||
DPRINTFR(Config, "Loading checkpoint dir '%s'\n", dir);
|
|
||||||
Checkpoint *cp = new Checkpoint(dir);
|
|
||||||
unserializeGlobals(cp);
|
|
||||||
SimObject::unserializeAll(cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Serializable::unserializeGlobals(Checkpoint *cp)
|
Serializable::unserializeGlobals(Checkpoint *cp)
|
||||||
{
|
{
|
||||||
|
@ -561,9 +550,9 @@ Checkpoint::dir()
|
||||||
|
|
||||||
|
|
||||||
Checkpoint::Checkpoint(const string &cpt_dir)
|
Checkpoint::Checkpoint(const string &cpt_dir)
|
||||||
: db(new IniFile), cptDir(cpt_dir)
|
: db(new IniFile), cptDir(setDir(cpt_dir))
|
||||||
{
|
{
|
||||||
string filename = cpt_dir + "/" + Checkpoint::baseFilename;
|
string filename = cptDir + "/" + Checkpoint::baseFilename;
|
||||||
if (!db->load(filename)) {
|
if (!db->load(filename)) {
|
||||||
fatal("Can't load checkpoint file '%s'\n", filename);
|
fatal("Can't load checkpoint file '%s'\n", filename);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,6 @@ class Serializable
|
||||||
static int ckptMaxCount;
|
static int ckptMaxCount;
|
||||||
static int ckptPrevCount;
|
static int ckptPrevCount;
|
||||||
static void serializeAll(const std::string &cpt_dir);
|
static void serializeAll(const std::string &cpt_dir);
|
||||||
static void unserializeAll(const std::string &cpt_dir);
|
|
||||||
static void unserializeGlobals(Checkpoint *cp);
|
static void unserializeGlobals(Checkpoint *cp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,18 @@ SimObject::init()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SimObject::loadState(Checkpoint *cp)
|
||||||
|
{
|
||||||
|
if (cp->sectionExists(name()))
|
||||||
|
unserialize(cp, name());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SimObject::initState()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SimObject::startup()
|
SimObject::startup()
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,17 +91,48 @@ class SimObject : public EventManager, public Serializable
|
||||||
|
|
||||||
virtual const std::string name() const { return params()->name; }
|
virtual const std::string name() const { return params()->name; }
|
||||||
|
|
||||||
// initialization pass of all objects.
|
// The following SimObject initialization methods are called from
|
||||||
// Gets invoked after construction, before unserialize.
|
// the instantiate() method in src/python/m5/simulate.py. See
|
||||||
|
// that function for details on how/when these methods are
|
||||||
|
// invoked.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init() is called after all C++ SimObjects have been created and
|
||||||
|
* all ports are connected. Initializations that are independent
|
||||||
|
* of unserialization but rely on a fully instantiated and
|
||||||
|
* connected SimObject graph should be done here.
|
||||||
|
*/
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* loadState() is called on each SimObject when restoring from a
|
||||||
|
* checkpoint. The default implementation simply calls
|
||||||
|
* unserialize() if there is a corresponding section in the
|
||||||
|
* checkpoint. However, objects can override loadState() to get
|
||||||
|
* other behaviors, e.g., doing other programmed initializations
|
||||||
|
* after unserialize(), or complaining if no checkpoint section is
|
||||||
|
* found.
|
||||||
|
*/
|
||||||
|
virtual void loadState(Checkpoint *cp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* initState() is called on each SimObject when *not* restoring
|
||||||
|
* from a checkpoint. This provides a hook for state
|
||||||
|
* initializations that are only required for a "cold start".
|
||||||
|
*/
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
// register statistics for this object
|
// register statistics for this object
|
||||||
virtual void regStats();
|
virtual void regStats();
|
||||||
virtual void regFormulas();
|
virtual void regFormulas();
|
||||||
virtual void resetStats();
|
virtual void resetStats();
|
||||||
|
|
||||||
// final initialization before simulation
|
/**
|
||||||
// all state is unserialized so
|
* startup() is the final initialization call before simulation.
|
||||||
|
* All state is initialized (including unserialized state, if any,
|
||||||
|
* such as the curTick value), so this is the appropriate place to
|
||||||
|
* schedule initial event(s) for objects that need them.
|
||||||
|
*/
|
||||||
virtual void startup();
|
virtual void startup();
|
||||||
|
|
||||||
// static: call nameOut() & serialize() on all SimObjects
|
// static: call nameOut() & serialize() on all SimObjects
|
||||||
|
|
Loading…
Reference in a new issue