using namespace std;
-Serializer *Serializeable::serializer = NULL;
-
-Serializeable::Serializeable()
- : serialized(false)
-{ }
-
-Serializeable::~Serializeable()
-{ }
-
-void
-Serializeable::mark()
-{
- if (!serialized)
- serializer->add_object(this);
-
- serialized = true;
-}
-
void
-Serializeable::nameOut(ostream &os)
+Serializable::nameOut(ostream &os)
{
os << "\n[" << name() << "]\n";
}
void
-Serializeable::nameOut(ostream &os, const string &_name)
+Serializable::nameOut(ostream &os, const string &_name)
{
os << "\n[" << _name << "]\n";
}
template <class T>
void
-paramOut(ostream &os, const std::string &name, const T& param)
+paramOut(ostream &os, const std::string &name, const T ¶m)
{
os << name << "=";
showParam(os, param);
template <class T>
void
paramIn(Checkpoint *cp, const std::string §ion,
- const std::string &name, T& param)
+ const std::string &name, T ¶m)
{
std::string str;
if (!cp->find(section, name, str) || !parseParam(str, param)) {
void
objParamIn(Checkpoint *cp, const std::string §ion,
- const std::string &name, Serializeable * ¶m)
+ const std::string &name, Serializable * ¶m)
{
if (!cp->findObj(section, name, param)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
INSTANTIATE_PARAM_TEMPLATES(string)
-#if 0
-// unneeded?
-void
-Serializeable::childOut(const string &name, Serializeable *child)
-{
- child->mark();
- if (child->name() == "")
- panic("child is unnamed");
+/////////////////////////////
- out() << name << "=" << child->name() << "\n";
-}
-#endif
-
-Serializer::Serializer()
-{ }
+/// Container for serializing global variables (not associated with
+/// any serialized object).
+class Globals : public Serializable
+{
+ public:
+ const string name() const;
+ void serialize(ostream &os);
+ void unserialize(Checkpoint *cp);
+};
-Serializer::~Serializer()
-{ }
+/// The one and only instance of the Globals class.
+Globals globals;
-ostream &
-Serializer::out() const
+const string
+Globals::name() const
{
- if (!output)
- panic("must set output before serializing");
-
- return *output;
+ return "Globals";
}
void
-Serializer::add_object(Serializeable *obj)
+Globals::serialize(ostream &os)
{
- objects.push_back(obj);
+ nameOut(os);
+ SERIALIZE_SCALAR(curTick);
+
+ nameOut(os, "MainEventQueue");
+ mainEventQueue.serialize(os);
}
void
-Serializer::add_objects()
+Globals::unserialize(Checkpoint *cp)
{
- mainEventQueue.mark();
-
- SimObject::SimObjectList::iterator i = SimObject::simObjectList.begin();
- SimObject::SimObjectList::iterator end = SimObject::simObjectList.end();
+ const string §ion = name();
+ UNSERIALIZE_SCALAR(curTick);
- while (i != end) {
- (*i)->mark();
- ++i;
- }
+ mainEventQueue.unserialize(cp, "MainEventQueue");
}
void
-Serializer::serialize()
+Serializable::serializeAll()
{
- if (Serializeable::serializer != NULL)
- panic("in process of serializing!");
-
- Serializeable::serializer = this;
-
- string dir = CheckpointDir();
+ string dir = Checkpoint::dir();
if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
- warn("could mkdir %s\n", dir);
+ fatal("couldn't mkdir %s\n", dir);
- string cpt_file = dir + "m5.cpt";
- output = new ofstream(cpt_file.c_str());
+ string cpt_file = dir + Checkpoint::baseFilename;
+ ofstream outstream(cpt_file.c_str());
time_t t = time(NULL);
- *output << "// checkpoint generated: " << ctime(&t);
-
- serlist_t list;
-
- add_objects();
- while (!objects.empty()) {
- Serializeable *obj = objects.front();
- DPRINTF(Serialize, "Serializing %s\n", obj->name());
- obj->nameOut(out());
- obj->serialize(out());
- objects.pop_front();
- list.push_back(obj);
- }
+ outstream << "// checkpoint generated: " << ctime(&t);
- while (!list.empty()) {
- list.front()->serialized = false;
- list.pop_front();
- }
+ globals.serialize(outstream);
+ SimObject::serializeAll(outstream);
+}
- Serializeable::serializer = NULL;
- delete output;
- output = NULL;
+void
+Serializable::unserializeGlobals(Checkpoint *cp)
+{
+ globals.unserialize(cp);
}
+
class SerializeEvent : public Event
{
protected:
};
SerializeEvent::SerializeEvent(Tick _when, Tick _repeat)
- : Event(&mainEventQueue, 990), repeat(_repeat)
+ : Event(&mainEventQueue, Serialize_Pri), repeat(_repeat)
{
setFlags(AutoDelete);
schedule(_when);
void
SerializeEvent::process()
{
- Serializer serial;
- serial.serialize();
+ Serializable::serializeAll();
if (repeat)
schedule(curTick + repeat);
}
-string __CheckpointDirBase;
+const char *Checkpoint::baseFilename = "m5.cpt";
+
+static string checkpointDirBase;
string
-CheckpointDir()
+Checkpoint::dir()
{
- if (__CheckpointDirBase.empty())
- return __CheckpointDirBase;
-
- return csprintf("%s/m5.%012d/", __CheckpointDirBase, curTick);
+ // use csprintf to insert curTick into directory name if it
+ // appears to have a format placeholder in it.
+ return (checkpointDirBase.find("%") != string::npos) ?
+ csprintf(checkpointDirBase, curTick) : checkpointDirBase;
}
void
-SetupCheckpoint(Tick when, Tick period)
+Checkpoint::setup(Tick when, Tick period)
{
new SerializeEvent(when, period);
}
SerializeParamContext serialParams("serialize");
-Param<string> serialize_dir(&serialParams,
- "dir",
- "dir to stick checkpoint in", ".");
+Param<string> serialize_dir(&serialParams, "dir",
+ "dir to stick checkpoint in "
+ "(sprintf format with cycle #)");
Param<Counter> serialize_cycle(&serialParams,
"cycle",
void
SerializeParamContext::checkParams()
{
- __CheckpointDirBase = serialize_dir;
+ if (serialize_dir.isValid()) {
+ checkpointDirBase = serialize_dir;
+ } else {
+ if (outputDirectory.empty())
+ checkpointDirBase = "m5.%012d";
+ else
+ checkpointDirBase = outputDirectory + "cpt.%012d";
+ }
+
+ // guarantee that directory ends with a '/'
+ if (checkpointDirBase[checkpointDirBase.size() - 1] != '/')
+ checkpointDirBase += "/";
+
if (serialize_cycle > 0)
- SetupCheckpoint(serialize_cycle, serialize_period);
+ Checkpoint::setup(serialize_cycle, serialize_period);
}
void
debug_serialize()
{
- Serializer serial;
- serial.serialize();
+ Serializable::serializeAll();
}
void
////////////////////////////////////////////////////////////////////////
//
-// SerializeableClass member definitions
+// SerializableClass member definitions
//
////////////////////////////////////////////////////////////////////////
-// Map of class names to SerializeableBuilder creation functions.
+// Map of class names to SerializableBuilder creation functions.
// Need to make this a pointer so we can force initialization on the
-// first reference; otherwise, some SerializeableClass constructors
+// first reference; otherwise, some SerializableClass constructors
// may be invoked before the classMap constructor.
-map<string,SerializeableClass::CreateFunc> *SerializeableClass::classMap = 0;
+map<string,SerializableClass::CreateFunc> *SerializableClass::classMap = 0;
-// SerializeableClass constructor: add mapping to classMap
-SerializeableClass::SerializeableClass(const string &className,
+// SerializableClass constructor: add mapping to classMap
+SerializableClass::SerializableClass(const string &className,
CreateFunc createFunc)
{
if (classMap == NULL)
- classMap = new map<string,SerializeableClass::CreateFunc>();
+ classMap = new map<string,SerializableClass::CreateFunc>();
if ((*classMap)[className])
{
//
//
-Serializeable *
-SerializeableClass::createObject(Checkpoint *cp,
+Serializable *
+SerializableClass::createObject(Checkpoint *cp,
const std::string §ion)
{
string className;
if (!cp->find(section, "type", className)) {
- fatal("Serializeable::create: no 'type' entry in section '%s'.\n",
+ fatal("Serializable::create: no 'type' entry in section '%s'.\n",
section);
}
CreateFunc createFunc = (*classMap)[className];
if (createFunc == NULL) {
- fatal("Serializeable::create: no create function for class '%s'.\n",
+ fatal("Serializable::create: no create function for class '%s'.\n",
className);
}
- Serializeable *object = createFunc(cp, section);
+ Serializable *object = createFunc(cp, section);
assert(object != NULL);
}
-Serializeable *
-Serializeable::create(Checkpoint *cp, const std::string §ion)
+Serializable *
+Serializable::create(Checkpoint *cp, const std::string §ion)
{
- Serializeable *object = SerializeableClass::createObject(cp, section);
+ Serializable *object = SerializableClass::createObject(cp, section);
object->unserialize(cp, section);
return object;
}
-Checkpoint::Checkpoint(const std::string &filename, const std::string &path,
+Checkpoint::Checkpoint(const std::string &cpt_dir, const std::string &path,
const ConfigNode *_configNode)
: db(new IniFile), basePath(path), configNode(_configNode)
{
+ string filename = cpt_dir + "/" + Checkpoint::baseFilename;
if (!db->load(filename)) {
fatal("Can't load checkpoint file '%s'\n", filename);
}
-
- mainEventQueue.unserialize(this, "MainEventQueue");
}
bool
Checkpoint::findObj(const std::string §ion, const std::string &entry,
- Serializeable *&value)
+ Serializable *&value)
{
string path;