--HG--
extra : convert_revision : 1552730090e0904fbc4e4c8f515b306355cb66f3
This commit is contained in:
Steve Reinhardt 2003-10-29 21:50:28 -08:00
commit 9a88c8e17d
17 changed files with 193 additions and 113 deletions

View file

@ -204,13 +204,13 @@ AlphaTlb::serialize(ostream &os)
}
void
AlphaTlb::unserialize(const IniFile *db, const string &section)
AlphaTlb::unserialize(Checkpoint *cp, const string &section)
{
UNSERIALIZE_SCALAR(size);
UNSERIALIZE_SCALAR(nlu);
for (int i = 0; i < size; i++) {
table[i].unserialize(db, csprintf("%s.PTE%d", section, i));
table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
if (table[i].valid) {
lookupTable.insert(make_pair(table[i].tag, i));
}

View file

@ -74,7 +74,7 @@ class AlphaTlb : public SimObject
// Checkpointing
virtual void serialize(std::ostream &os);
virtual void unserialize(const IniFile *db, const std::string &section);
virtual void unserialize(Checkpoint *cp, const std::string &section);
};
class AlphaItb : public AlphaTlb

View file

@ -34,7 +34,7 @@
#include "base/misc.hh"
class FullCPU;
class IniFile;
class Checkpoint;
#define TARGET_ALPHA
@ -160,7 +160,7 @@ class AlphaISA
uint8_t opcode, ra; // current instruction details (for intr's)
void serialize(std::ostream &os);
void unserialize(const IniFile *db, const std::string &section);
void unserialize(Checkpoint *cp, const std::string &section);
};
static StaticInstPtr<AlphaISA> decodeInst(MachInst);

View file

@ -108,10 +108,10 @@ ExecContext::serialize(ostream &os)
void
ExecContext::unserialize(const IniFile *db, const std::string &section)
ExecContext::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ENUM(_status);
regs.unserialize(db, section);
regs.unserialize(cp, section);
// thread_num and cpu_id are deterministic from the config
UNSERIALIZE_SCALAR(func_exe_insn);
}

View file

@ -142,7 +142,7 @@ class ExecContext
void regStats(const std::string &name);
void serialize(std::ostream &os);
void unserialize(const IniFile *db, const std::string &section);
void unserialize(Checkpoint *cp, const std::string &section);
#ifdef FULL_SYSTEM
bool validInstAddr(Addr addr) { return true; }

View file

@ -262,6 +262,7 @@ SimpleCPU::serialize(ostream &os)
{
SERIALIZE_ENUM(_status);
SERIALIZE_SCALAR(inst);
nameOut(os, csprintf("%s.xc", name()));
xc->serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
@ -270,14 +271,14 @@ SimpleCPU::serialize(ostream &os)
}
void
SimpleCPU::unserialize(const IniFile *db, const string &section)
SimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
UNSERIALIZE_ENUM(_status);
UNSERIALIZE_SCALAR(inst);
xc->unserialize(db, section);
tickEvent.unserialize(db, csprintf("%s.tickEvent", name()));
xc->unserialize(cp, csprintf("%s.xc", section));
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
cacheCompletionEvent
.unserialize(db, csprintf("%s.cacheCompletionEvent", name()));
.unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
}
void

View file

@ -49,7 +49,7 @@ class GDBListener;
#endif // FULL_SYSTEM
class MemInterface;
class IniFile;
class Checkpoint;
namespace Trace {
class InstRecord;
@ -259,7 +259,7 @@ class SimpleCPU : public BaseCPU
void processCacheCompletion();
virtual void serialize(std::ostream &os);
virtual void unserialize(const IniFile *db, const std::string &section);
virtual void unserialize(Checkpoint *cp, const std::string &section);
template <class T>
Fault read(Addr addr, T& data, unsigned flags);

View file

@ -44,7 +44,7 @@ typedef uint64_t UINT64;
#include <ostream>
#include <string>
class IniFile;
class Checkpoint;
#endif
@ -82,7 +82,7 @@ struct AlphaAccess
#ifndef CONSOLE
void serialize(std::ostream &os);
void unserialize(const IniFile *db, const std::string &section);
void unserialize(Checkpoint *cp, const std::string &section);
#endif
};

View file

@ -188,7 +188,7 @@ AlphaAccess::serialize(ostream &os)
}
void
AlphaAccess::unserialize(const IniFile *db, const std::string &section)
AlphaAccess::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(last_offset);
UNSERIALIZE_SCALAR(version);
@ -216,9 +216,9 @@ AlphaConsole::serialize(ostream &os)
}
void
AlphaConsole::unserialize(const IniFile *db, const std::string &section)
AlphaConsole::unserialize(Checkpoint *cp, const std::string &section)
{
alphaAccess->unserialize(db, section);
alphaAccess->unserialize(cp, section);
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)

View file

@ -101,7 +101,7 @@ class AlphaConsole : public MmapDevice
* standard serialization routines for checkpointing
*/
virtual void serialize(std::ostream &os);
virtual void unserialize(const IniFile *db, const std::string &section);
virtual void unserialize(Checkpoint *cp, const std::string &section);
};
#endif // __ALPHA_CONSOLE_HH__

View file

@ -319,7 +319,7 @@ SimConsole::serialize(ostream &os)
}
void
SimConsole::unserialize(const IniFile *db, const std::string &section)
SimConsole::unserialize(Checkpoint *cp, const std::string &section)
{
}

View file

@ -129,7 +129,7 @@ class SimConsole : public SimObject
void setInt(int bits);
virtual void serialize(std::ostream &os);
virtual void unserialize(const IniFile *db, const std::string &section);
virtual void unserialize(Checkpoint *cp, const std::string &section);
};
class ConsoleListener : public SimObject

View file

@ -129,7 +129,7 @@ Event::serialize(std::ostream &os)
void
Event::unserialize(const IniFile *db, const string &section)
Event::unserialize(Checkpoint *cp, const string &section)
{
if (scheduled())
deschedule();
@ -154,39 +154,51 @@ Event::unserialize(const IniFile *db, const string &section)
void
EventQueue::nameChildren()
{
#if 0
int j = 0;
int numEvents = 0;
Event *event = head;
while (event) {
stringstream stream;
ccprintf(stream, "%s.event%d", name(), j++);
event->setName(stream.str());
if (event->getFlags(Event::AutoSerialize)) {
event->setName(csprintf("%s.event%d", name(), numEvents++));
}
event = event->next;
}
#endif
numAutoSerializeEvents = numEvents;
}
void
EventQueue::serialize(ostream &os)
{
#if 0
string objects = "";
// should have been set by a preceding call to nameChildren()
assert(numAutoSerializeEvents >= 0);
SERIALIZE_SCALAR(numAutoSerializeEvents);
int numEvents = 0;
Event *event = head;
while (event) {
objects += event->name();
objects += " ";
if (event->getFlags(Event::AutoSerialize)) {
event->nameOut(os);
event->serialize(os);
numEvents++;
}
event = event->next;
}
nameOut(os, "Serialized");
SERIALIZE_SCALAR(objects);
#endif
assert(numEvents == numAutoSerializeEvents);
}
void
EventQueue::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(numAutoSerializeEvents);
for (int eventNum = 0; eventNum < numAutoSerializeEvents; ++eventNum) {
Serializeable::create(cp, csprintf("%s.event%d", section, eventNum));
}
}
void
EventQueue::dump()
{

View file

@ -73,7 +73,8 @@ class Event : public Serializeable, public FastAlloc
None = 0x0,
Squashed = 0x1,
Scheduled = 0x2,
AutoDelete = 0x4
AutoDelete = 0x4,
AutoSerialize = 0x8
};
bool getFlags(Flags f) const { return (_flags & f) == f; }
@ -190,7 +191,7 @@ class Event : public Serializeable, public FastAlloc
};
virtual void serialize(std::ostream &os);
virtual void unserialize(const IniFile *db, const std::string &section);
virtual void unserialize(Checkpoint *cp, const std::string &section);
};
template <class T, void (T::* F)()>
@ -221,6 +222,9 @@ class EventQueue : public Serializeable
private:
Event *head;
// only used to hold value between nameChildren() and serialize()
int numAutoSerializeEvents;
void insert(Event *event);
void remove(Event *event);
@ -228,7 +232,7 @@ class EventQueue : public Serializeable
// constructor
EventQueue(const std::string &n)
: Serializeable(n), head(NULL)
: Serializeable(n), head(NULL), numAutoSerializeEvents(-1)
{}
// schedule the given event on this queue
@ -264,6 +268,7 @@ class EventQueue : public Serializeable
virtual void nameChildren();
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
};

View file

@ -97,7 +97,7 @@ parseParam(const string &s, T &value)
template <class T>
void
showParam(ostream &os, const T &value)
showParam(ostream &os, T const &value)
{
os << value;
}
@ -277,7 +277,7 @@ template VectorParam<type>;
// types that can use the above templates
#define INSTANTIATE_PARAM_TEMPLATES(type, typestr) \
template bool parseParam<type>(const string &s, type &value); \
template void showParam<type>(ostream &os, const type &value); \
template void showParam<type>(ostream &os, type const &value); \
template void Param<type>::parse(const string &); \
template void VectorParam<type>::parse(const string &); \
template void Param<type>::showValue(ostream &) const; \

View file

@ -43,6 +43,7 @@
#include "sim/sim_events.hh"
#include "sim/sim_object.hh"
#include "base/trace.hh"
#include "sim/config_node.hh"
using namespace std;
@ -88,11 +89,11 @@ paramOut(ostream &os, const std::string &name, const T& param)
template <class T>
void
paramIn(const IniFile *db, const std::string &section,
paramIn(Checkpoint *cp, const std::string &section,
const std::string &name, T& param)
{
std::string str;
if (!db->find(section, name, str) || !parseParam(str, param)) {
if (!cp->find(section, name, str) || !parseParam(str, param)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
}
@ -116,11 +117,11 @@ arrayParamOut(ostream &os, const std::string &name,
template <class T>
void
arrayParamIn(const IniFile *db, const std::string &section,
arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, T *param, int size)
{
std::string str;
if (!db->find(section, name, str)) {
if (!cp->find(section, name, str)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
@ -159,17 +160,27 @@ arrayParamIn(const IniFile *db, const std::string &section,
}
void
objParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, Serializeable * &param)
{
if (!cp->findObj(section, name, param)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
}
#define INSTANTIATE_PARAM_TEMPLATES(type) \
template void \
paramOut(ostream &os, const std::string &name, const type &param); \
paramOut(ostream &os, const std::string &name, type const &param); \
template void \
paramIn(const IniFile *db, const std::string &section, \
paramIn(Checkpoint *cp, const std::string &section, \
const std::string &name, type & param); \
template void \
arrayParamOut(ostream &os, const std::string &name, \
const type *param, int size); \
type const *param, int size); \
template void \
arrayParamIn(const IniFile *db, const std::string &section, \
arrayParamIn(Checkpoint *cp, const std::string &section, \
const std::string &name, type *param, int size);
@ -421,41 +432,74 @@ SerializeableClass::SerializeableClass(const string &className,
//
//
Serializeable *
SerializeableClass::createObject(IniFile &configDB,
const string &configClassName)
SerializeableClass::createObject(Checkpoint *cp,
const std::string &section)
{
// find simulation object class name from configuration class
// (specified by 'type=' parameter)
string simObjClassName;
string className;
if (!configDB.findDefault(configClassName, "type", simObjClassName)) {
cerr << "Configuration class '" << configClassName << "' not found."
<< endl;
abort();
if (!cp->find(section, "type", className)) {
fatal("Serializeable::create: no 'type' entry in section '%s'.\n",
section);
}
// look up className to get appropriate createFunc
if (classMap->find(simObjClassName) == classMap->end()) {
cerr << "Simulator object class '" << simObjClassName << "' not found."
<< endl;
abort();
CreateFunc createFunc = (*classMap)[className];
if (createFunc == NULL) {
fatal("Serializeable::create: no create function for class '%s'.\n",
className);
}
CreateFunc createFunc = (*classMap)[simObjClassName];
// builder instance
SerializeableBuilder *objectBuilder = (*createFunc)();
assert(objectBuilder != NULL);
// now create the actual simulation object
Serializeable *object = objectBuilder->create();
Serializeable *object = createFunc(cp, section);
assert(object != NULL);
// done with the SerializeableBuilder now
delete objectBuilder;
return object;
}
Serializeable *
Serializeable::create(Checkpoint *cp, const std::string &section)
{
Serializeable *object = SerializeableClass::createObject(cp, section);
object->unserialize(cp, section);
return object;
}
Checkpoint::Checkpoint(const std::string &filename, const std::string &path,
const ConfigNode *_configNode)
: db(new IniFile), basePath(path), configNode(_configNode)
{
if (!db->load(filename)) {
fatal("Can't load checkpoint file '%s'\n", filename);
}
mainEventQueue.unserialize(this, "MainEventQueue");
}
bool
Checkpoint::find(const std::string &section, const std::string &entry,
std::string &value)
{
return db->find(section, entry, value);
}
bool
Checkpoint::findObj(const std::string &section, const std::string &entry,
Serializeable *&value)
{
string path;
if (!db->find(section, entry, path))
return false;
if ((value = configNode->resolveSimObject(path)) != NULL)
return true;
if ((value = objMap[path]) != NULL)
return true;
return false;
}

View file

@ -41,13 +41,14 @@
#include "sim/host.hh"
#include "sim/configfile.hh"
class IniFile;
class Serializeable;
class Checkpoint;
template <class T>
void paramOut(std::ostream &os, const std::string &name, const T& param);
template <class T>
void paramIn(const IniFile *db, const std::string &section,
void paramIn(Checkpoint *cp, const std::string &section,
const std::string &name, T& param);
template <class T>
@ -55,16 +56,21 @@ void arrayParamOut(std::ostream &os, const std::string &name,
const T *param, int size);
template <class T>
void arrayParamIn(const IniFile *db, const std::string &section,
void arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, T *param, int size);
void
objParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, Serializeable * &param);
//
// These macros are streamlined to use in serialize/unserialize
// functions. It's assumed that serialize() has a parameter 'os' for
// the ostream, and unserialize() has parameters 'db' and 'section'.
// the ostream, and unserialize() has parameters 'cp' and 'section'.
#define SERIALIZE_SCALAR(scalar) paramOut(os, #scalar, scalar)
#define UNSERIALIZE_SCALAR(scalar) paramIn(db, section, #scalar, scalar)
#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, section, #scalar, scalar)
// ENUMs are like SCALARs, but we cast them to ints on the way out
#define SERIALIZE_ENUM(scalar) paramOut(os, #scalar, (int)scalar)
@ -72,7 +78,7 @@ void arrayParamIn(const IniFile *db, const std::string &section,
#define UNSERIALIZE_ENUM(scalar) \
do { \
int tmp; \
paramIn(db, section, #scalar, tmp); \
paramIn(cp, section, #scalar, tmp); \
scalar = (typeof(scalar))tmp; \
} while (0)
@ -80,7 +86,16 @@ void arrayParamIn(const IniFile *db, const std::string &section,
arrayParamOut(os, #member, member, size)
#define UNSERIALIZE_ARRAY(member, size) \
arrayParamIn(db, section, #member, member, size)
arrayParamIn(cp, section, #member, member, size)
#define SERIALIZE_OBJPTR(objptr) paramOut(os, #objptr, (objptr)->name())
#define UNSERIALIZE_OBJPTR(objptr) \
do { \
Serializeable *sptr; \
objParamIn(cp, section, #objptr, sptr); \
objptr = dynamic_cast<typeof(objptr)>(sptr); \
} while (0)
/*
* Basic support for object serialization.
@ -113,7 +128,10 @@ class Serializeable
virtual void nameChildren() {}
virtual void serialize(std::ostream& os) {}
virtual void unserialize(const IniFile *db, const std::string &section) {}
virtual void unserialize(Checkpoint *cp, const std::string &section) {}
static Serializeable *create(Checkpoint *cp,
const std::string &section);
};
class Serializer
@ -187,7 +205,8 @@ class SerializeableClass
// for the object (specified by the second string argument), and
// an optional config hierarchy node (specified by the third
// argument). A pointer to the new SerializeableBuilder is returned.
typedef SerializeableBuilder *(*CreateFunc)();
typedef Serializeable *(*CreateFunc)(Checkpoint *cp,
const std::string &section);
static std::map<std::string,CreateFunc> *classMap;
@ -200,9 +219,8 @@ class SerializeableClass
// create Serializeable given name of class and pointer to
// configuration hierarchy node
static Serializeable *createObject(IniFile &configDB,
const std::string &configClassName);
static Serializeable *createObject(Checkpoint *cp,
const std::string &section);
};
//
@ -210,29 +228,29 @@ class SerializeableClass
// SerializeableBuilder and SerializeableClass objects
//
#define CREATE_SERIALIZEABLE(OBJ_CLASS) \
OBJ_CLASS *OBJ_CLASS##Builder::create()
#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \
class OBJ_CLASS##Builder : public SerializeableBuilder \
{ \
public: \
\
OBJ_CLASS##Builder() {} \
virtual ~OBJ_CLASS##Builder() {} \
\
OBJ_CLASS *create(); \
}; \
\
\
SerializeableBuilder * \
new##OBJ_CLASS##Builder() \
{ \
return new OBJ_CLASS##Builder(); \
} \
\
SerializeableClass the##OBJ_CLASS##Class(CLASS_NAME, \
new##OBJ_CLASS##Builder);
OBJ_CLASS::createForUnserialize);
class Checkpoint
{
private:
IniFile *db;
const std::string basePath;
const ConfigNode *configNode;
std::map<std::string, Serializeable*> objMap;
public:
Checkpoint(const std::string &filename, const std::string &path,
const ConfigNode *_configNode);
bool find(const std::string &section, const std::string &entry,
std::string &value);
bool findObj(const std::string &section, const std::string &entry,
Serializeable *&value);
};
//