summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/alpha_memory.cc4
-rw-r--r--arch/alpha/alpha_memory.hh2
-rw-r--r--arch/alpha/isa_traits.hh4
-rw-r--r--cpu/exec_context.cc4
-rw-r--r--cpu/exec_context.hh2
-rw-r--r--cpu/simple_cpu/simple_cpu.cc9
-rw-r--r--cpu/simple_cpu/simple_cpu.hh4
-rw-r--r--dev/alpha_access.h4
-rw-r--r--dev/alpha_console.cc6
-rw-r--r--dev/alpha_console.hh2
-rw-r--r--dev/console.cc2
-rw-r--r--dev/console.hh2
-rw-r--r--sim/eventq.cc48
-rw-r--r--sim/eventq.hh11
-rw-r--r--sim/param.cc4
-rw-r--r--sim/serialize.cc108
-rw-r--r--sim/serialize.hh88
17 files changed, 192 insertions, 112 deletions
diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc
index 7c0b1120f..c79b821d0 100644
--- a/arch/alpha/alpha_memory.cc
+++ b/arch/alpha/alpha_memory.cc
@@ -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));
}
diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh
index fc4d46191..bfcd313e2 100644
--- a/arch/alpha/alpha_memory.hh
+++ b/arch/alpha/alpha_memory.hh
@@ -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
diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh
index fbdcffbcf..406ffb6f3 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -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);
diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc
index b869a8c4d..195c9daad 100644
--- a/cpu/exec_context.cc
+++ b/cpu/exec_context.cc
@@ -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);
}
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index 6938b369f..cb826a15e 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -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; }
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index 3179b7b1f..519a8cd4d 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -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
diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh
index 61831cb3c..61c9143ba 100644
--- a/cpu/simple_cpu/simple_cpu.hh
+++ b/cpu/simple_cpu/simple_cpu.hh
@@ -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);
diff --git a/dev/alpha_access.h b/dev/alpha_access.h
index c145fa2a3..eb551a359 100644
--- a/dev/alpha_access.h
+++ b/dev/alpha_access.h
@@ -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
};
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc
index 969b1e4c3..6fe57edb5 100644
--- a/dev/alpha_console.cc
+++ b/dev/alpha_console.cc
@@ -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)
diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh
index e4aeb2417..9e774773e 100644
--- a/dev/alpha_console.hh
+++ b/dev/alpha_console.hh
@@ -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__
diff --git a/dev/console.cc b/dev/console.cc
index 749add532..2378f8c75 100644
--- a/dev/console.cc
+++ b/dev/console.cc
@@ -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)
{
}
diff --git a/dev/console.hh b/dev/console.hh
index 6746f90b6..fd02e7a9a 100644
--- a/dev/console.hh
+++ b/dev/console.hh
@@ -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
diff --git a/sim/eventq.cc b/sim/eventq.cc
index 77eb490c7..ef813eb13 100644
--- a/sim/eventq.cc
+++ b/sim/eventq.cc
@@ -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 += " ";
- event->serialize(os);
-
+ 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()
{
diff --git a/sim/eventq.hh b/sim/eventq.hh
index a8eae1248..11bfe3a4e 100644
--- a/sim/eventq.hh
+++ b/sim/eventq.hh
@@ -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);
};
diff --git a/sim/param.cc b/sim/param.cc
index 5f3f604c1..7affe4786 100644
--- a/sim/param.cc
+++ b/sim/param.cc
@@ -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; \
diff --git a/sim/serialize.cc b/sim/serialize.cc
index f838acc8d..dfd495a32 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -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];
+ Serializeable *object = createFunc(cp, section);
- // builder instance
- SerializeableBuilder *objectBuilder = (*createFunc)();
+ assert(object != NULL);
- assert(objectBuilder != NULL);
+ return object;
+}
- // now create the actual simulation object
- Serializeable *object = objectBuilder->create();
- assert(object != NULL);
+Serializeable *
+Serializeable::create(Checkpoint *cp, const std::string &section)
+{
+ Serializeable *object = SerializeableClass::createObject(cp, section);
+ object->unserialize(cp, section);
+ return object;
+}
- // done with the SerializeableBuilder now
- delete objectBuilder;
- 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;
+}
diff --git a/sim/serialize.hh b/sim/serialize.hh
index 4e0dbd1bd..b615e6527 100644
--- a/sim/serialize.hh
+++ b/sim/serialize.hh
@@ -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);
+#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \
+SerializeableClass the##OBJ_CLASS##Class(CLASS_NAME, \
+ 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);
+};
//