diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sim/serialize.cc | 429 | ||||
-rw-r--r-- | src/sim/serialize.hh | 640 |
2 files changed, 479 insertions, 590 deletions
diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index a03a396b3..095a44c34 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -57,12 +57,8 @@ #include <string> #include <vector> -#include "arch/generic/vec_reg.hh" -#include "base/framebuffer.hh" #include "base/inifile.hh" -#include "base/logging.hh" #include "base/output.hh" -#include "base/str.hh" #include "base/trace.hh" #include "debug/Checkpoint.hh" #include "sim/eventq.hh" @@ -75,412 +71,11 @@ using namespace std; -// -// The base implementations use to_number for parsing and '<<' for -// displaying, suitable for integer types. -// -template <class T> -bool -parseParam(const string &s, T &value) -{ - return to_number(s, value); -} - -template <class T> -void -showParam(CheckpointOut &os, const T &value) -{ - os << value; -} - -// -// Template specializations: -// - char (8-bit integer) -// - floating-point types -// - bool -// - string -// - -// Treat 8-bit ints (chars) as ints on output, not as chars -template <> -void -showParam(CheckpointOut &os, const char &value) -{ - os << (int)value; -} - - -template <> -void -showParam(CheckpointOut &os, const signed char &value) -{ - os << (int)value; -} - - -template <> -void -showParam(CheckpointOut &os, const unsigned char &value) -{ - os << (unsigned int)value; -} - - -template <> -bool -parseParam(const string &s, float &value) -{ - return to_number(s, value); -} - -template <> -bool -parseParam(const string &s, double &value) -{ - return to_number(s, value); -} - -template <> -bool -parseParam(const string &s, bool &value) -{ - return to_bool(s, value); -} - -// Display bools as strings -template <> -void -showParam(CheckpointOut &os, const bool &value) -{ - os << (value ? "true" : "false"); -} - - -// String requires no processing to speak of -template <> -bool -parseParam(const string &s, string &value) -{ - value = s; - return true; -} - int Serializable::ckptMaxCount = 0; int Serializable::ckptCount = 0; int Serializable::ckptPrevCount = -1; std::stack<std::string> Serializable::path; -template <class T> -void -paramOut(CheckpointOut &os, const string &name, const T ¶m) -{ - os << name << "="; - showParam(os, param); - os << "\n"; -} - -template <class T> -void -arrayParamOut(CheckpointOut &os, const string &name, const vector<T> ¶m) -{ - typename vector<T>::size_type size = param.size(); - os << name << "="; - if (size > 0) - showParam(os, param[0]); - for (typename vector<T>::size_type i = 1; i < size; ++i) { - os << " "; - showParam(os, param[i]); - } - os << "\n"; -} - -template <class T> -void -arrayParamOut(CheckpointOut &os, const string &name, const list<T> ¶m) -{ - typename list<T>::const_iterator it = param.begin(); - - os << name << "="; - if (param.size() > 0) - showParam(os, *it); - it++; - while (it != param.end()) { - os << " "; - showParam(os, *it); - it++; - } - os << "\n"; -} - -template <class T> -void -arrayParamOut(CheckpointOut &os, const string &name, const set<T> ¶m) -{ - typename set<T>::const_iterator it = param.begin(); - - os << name << "="; - if (param.size() > 0) - showParam(os, *it); - it++; - while (it != param.end()) { - os << " "; - showParam(os, *it); - it++; - } - os << "\n"; -} - -template <class T> -void -paramIn(CheckpointIn &cp, const string &name, T ¶m) -{ - const string §ion(Serializable::currentSection()); - string str; - if (!cp.find(section, name, str) || !parseParam(str, param)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } -} - -template <class T> -bool -optParamIn(CheckpointIn &cp, const string &name, T ¶m, bool warn) -{ - const string §ion(Serializable::currentSection()); - string str; - if (!cp.find(section, name, str) || !parseParam(str, param)) { - if (warn) - warn("optional parameter %s:%s not present\n", section, name); - return false; - } else { - return true; - } -} - -template <class T> -void -arrayParamOut(CheckpointOut &os, const string &name, - const T *param, unsigned size) -{ - os << name << "="; - if (size > 0) - showParam(os, param[0]); - for (unsigned i = 1; i < size; ++i) { - os << " "; - showParam(os, param[i]); - } - os << "\n"; -} - - -template <class T> -void -arrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size) -{ - const string §ion(Serializable::currentSection()); - string str; - if (!cp.find(section, name, str)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } - - // code below stolen from VectorParam<T>::parse(). - // it would be nice to unify these somehow... - - vector<string> tokens; - - tokenize(tokens, str, ' '); - - // Need this if we were doing a vector - // value.resize(tokens.size()); - - if (tokens.size() != size) { - fatal("Array size mismatch on %s:%s'\n", section, name); - } - - for (vector<string>::size_type i = 0; i < tokens.size(); i++) { - // need to parse into local variable to handle vector<bool>, - // for which operator[] returns a special reference class - // that's not the same as 'bool&', (since it's a packed - // vector) - T scalar_value; - if (!parseParam(tokens[i], scalar_value)) { - string err("could not parse \""); - - err += str; - err += "\""; - - fatal(err); - } - - // assign parsed value to vector - param[i] = scalar_value; - } -} - -template <class T> -void -arrayParamIn(CheckpointIn &cp, const string &name, vector<T> ¶m) -{ - const string §ion(Serializable::currentSection()); - string str; - if (!cp.find(section, name, str)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } - - // code below stolen from VectorParam<T>::parse(). - // it would be nice to unify these somehow... - - vector<string> tokens; - - tokenize(tokens, str, ' '); - - // Need this if we were doing a vector - // value.resize(tokens.size()); - - param.resize(tokens.size()); - - for (vector<string>::size_type i = 0; i < tokens.size(); i++) { - // need to parse into local variable to handle vector<bool>, - // for which operator[] returns a special reference class - // that's not the same as 'bool&', (since it's a packed - // vector) - T scalar_value; - if (!parseParam(tokens[i], scalar_value)) { - string err("could not parse \""); - - err += str; - err += "\""; - - fatal(err); - } - - // assign parsed value to vector - param[i] = scalar_value; - } -} - -template <class T> -void -arrayParamIn(CheckpointIn &cp, const string &name, list<T> ¶m) -{ - const string §ion(Serializable::currentSection()); - string str; - if (!cp.find(section, name, str)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } - param.clear(); - - vector<string> tokens; - tokenize(tokens, str, ' '); - - for (vector<string>::size_type i = 0; i < tokens.size(); i++) { - T scalar_value; - if (!parseParam(tokens[i], scalar_value)) { - string err("could not parse \""); - - err += str; - err += "\""; - - fatal(err); - } - - // assign parsed value to vector - param.push_back(scalar_value); - } -} - -template <class T> -void -arrayParamIn(CheckpointIn &cp, const string &name, set<T> ¶m) -{ - const string §ion(Serializable::currentSection()); - string str; - if (!cp.find(section, name, str)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } - param.clear(); - - vector<string> tokens; - tokenize(tokens, str, ' '); - - for (vector<string>::size_type i = 0; i < tokens.size(); i++) { - T scalar_value; - if (!parseParam(tokens[i], scalar_value)) { - string err("could not parse \""); - - err += str; - err += "\""; - - fatal(err); - } - - // assign parsed value to vector - param.insert(scalar_value); - } -} - - -void -objParamIn(CheckpointIn &cp, const string &name, SimObject * ¶m) -{ - const string §ion(Serializable::currentSection()); - if (!cp.findObj(section, name, param)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } -} - - -#define INSTANTIATE_PARAM_TEMPLATES(type) \ - template void \ - paramOut(CheckpointOut &os, const string &name, type const ¶m); \ - template void \ - paramIn(CheckpointIn &cp, const string &name, type & param); \ - template bool \ - optParamIn(CheckpointIn &cp, const string &name, type & param, \ - bool warn); \ - template void \ - arrayParamOut(CheckpointOut &os, const string &name, \ - type const *param, unsigned size); \ - template void \ - arrayParamIn(CheckpointIn &cp, const string &name, \ - type *param, unsigned size); \ - template void \ - arrayParamOut(CheckpointOut &os, const string &name, \ - const vector<type> ¶m); \ - template void \ - arrayParamIn(CheckpointIn &cp, const string &name, \ - vector<type> ¶m); \ - template void \ - arrayParamOut(CheckpointOut &os, const string &name, \ - const list<type> ¶m); \ - template void \ - arrayParamIn(CheckpointIn &cp, const string &name, \ - list<type> ¶m); - -INSTANTIATE_PARAM_TEMPLATES(char) -INSTANTIATE_PARAM_TEMPLATES(signed char) -INSTANTIATE_PARAM_TEMPLATES(unsigned char) -INSTANTIATE_PARAM_TEMPLATES(signed short) -INSTANTIATE_PARAM_TEMPLATES(unsigned short) -INSTANTIATE_PARAM_TEMPLATES(signed int) -INSTANTIATE_PARAM_TEMPLATES(unsigned int) -INSTANTIATE_PARAM_TEMPLATES(signed long) -INSTANTIATE_PARAM_TEMPLATES(unsigned long) -INSTANTIATE_PARAM_TEMPLATES(signed long long) -INSTANTIATE_PARAM_TEMPLATES(unsigned long long) -INSTANTIATE_PARAM_TEMPLATES(bool) -INSTANTIATE_PARAM_TEMPLATES(float) -INSTANTIATE_PARAM_TEMPLATES(double) -INSTANTIATE_PARAM_TEMPLATES(string) -INSTANTIATE_PARAM_TEMPLATES(Pixel) -INSTANTIATE_PARAM_TEMPLATES(VecRegContainer<8>) -INSTANTIATE_PARAM_TEMPLATES(VecRegContainer<16>) - -// set is only used with strings and furthermore doesn't agree with Pixel -template void -arrayParamOut(CheckpointOut &, const string &, const set<string> &); -template void -arrayParamIn(CheckpointIn &, const string &, set<string> &); - ///////////////////////////// /// Container for serializing global variables (not associated with @@ -645,12 +240,6 @@ Serializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp) cp << "\n[" << Serializable::currentSection() << "]\n"; } -void -debug_serialize(const string &cpt_dir) -{ - Serializable::serializeAll(cpt_dir); -} - const std::string & Serializable::currentSection() { @@ -681,7 +270,6 @@ CheckpointIn::dir() return currentDirectory; } - CheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver) : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir)) { @@ -708,7 +296,6 @@ CheckpointIn::find(const string §ion, const string &entry, string &value) return db->find(section, entry, value); } - bool CheckpointIn::findObj(const string §ion, const string &entry, SimObject *&value) @@ -722,9 +309,23 @@ CheckpointIn::findObj(const string §ion, const string &entry, return true; } - bool CheckpointIn::sectionExists(const string §ion) { return db->sectionExists(section); } + +void +objParamIn(CheckpointIn &cp, const string &name, SimObject * ¶m) +{ + const string §ion(Serializable::currentSection()); + if (!cp.findObj(section, name, param)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } +} + +void +debug_serialize(const string &cpt_dir) +{ + Serializable::serializeAll(cpt_dir); +} diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index b3081ad5a..adaefdd84 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -60,166 +60,65 @@ #include <vector> #include "base/bitunion.hh" +#include "base/logging.hh" +#include "base/str.hh" -class CheckpointIn; class IniFile; -class Serializable; class SimObject; class SimObjectResolver; typedef std::ostream CheckpointOut; - -template <class T> -void paramOut(CheckpointOut &cp, const std::string &name, const T ¶m); - -template <typename T> -void -paramOut(CheckpointOut &cp, const std::string &name, const BitUnionType<T> &p) -{ - paramOut(cp, name, static_cast<BitUnionBaseType<T> >(p)); -} - -template <class T> -void paramIn(CheckpointIn &cp, const std::string &name, T ¶m); - -template <typename T> -void -paramIn(CheckpointIn &cp, const std::string &name, BitUnionType<T> &p) -{ - BitUnionBaseType<T> b; - paramIn(cp, name, b); - p = b; -} - -template <class T> -bool optParamIn(CheckpointIn &cp, const std::string &name, T ¶m, - bool warn = true); - -template <typename T> -bool -optParamIn(CheckpointIn &cp, const std::string &name, - BitUnionType<T> &p, bool warn = true) -{ - BitUnionBaseType<T> b; - if (optParamIn(cp, name, b, warn)) { - p = b; - return true; - } else { - return false; - } -} - -template <class T> -void arrayParamOut(CheckpointOut &cp, const std::string &name, - const T *param, unsigned size); - -template <class T> -void arrayParamOut(CheckpointOut &cp, const std::string &name, - const std::vector<T> ¶m); - -template <class T> -void arrayParamOut(CheckpointOut &cp, const std::string &name, - const std::list<T> ¶m); - -template <class T> -void arrayParamOut(CheckpointOut &cp, const std::string &name, - const std::set<T> ¶m); - -template <class T> -void arrayParamIn(CheckpointIn &cp, const std::string &name, - T *param, unsigned size); - -template <class T> -void arrayParamIn(CheckpointIn &cp, const std::string &name, - std::vector<T> ¶m); - -template <class T> -void arrayParamIn(CheckpointIn &cp, const std::string &name, - std::list<T> ¶m); - -template <class T> -void arrayParamIn(CheckpointIn &cp, const std::string &name, - std::set<T> ¶m); - -void -objParamIn(CheckpointIn &cp, const std::string &name, SimObject * ¶m); - -template <class T> -static void -arrayParamOut(CheckpointOut &cp, const std::string &name, - const BitUnionType<T> *param, unsigned size) -{ - // We copy the array into a vector. This is needed since we cannot - // directly typecast a pointer to BitUnionType<T> into a pointer - // of BitUnionBaseType<T> but we can typecast BitUnionType<T> - // to BitUnionBaseType<T> since we overloaded the typecast operator - std::vector<BitUnionBaseType<T>> bitunion_vec(param, param + size); - - arrayParamOut(cp, name, bitunion_vec); -} - -template <class T> -static void -arrayParamIn(CheckpointIn &cp, const std::string &name, - BitUnionType<T> *param, unsigned size) +class CheckpointIn { - std::vector<BitUnionBaseType<T>> bitunion_vec(size); - - arrayParamIn(cp, name, bitunion_vec); - std::copy(bitunion_vec.begin(), bitunion_vec.end(), param); -} + private: -// -// 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 'cp' and 'section'. -#define SERIALIZE_SCALAR(scalar) paramOut(cp, #scalar, scalar) + IniFile *db; -#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, #scalar, scalar) -#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, #scalar, scalar) + SimObjectResolver &objNameResolver; -// ENUMs are like SCALARs, but we cast them to ints on the way out -#define SERIALIZE_ENUM(scalar) paramOut(cp, #scalar, (int)scalar) + public: + CheckpointIn(const std::string &cpt_dir, SimObjectResolver &resolver); + ~CheckpointIn(); -#define UNSERIALIZE_ENUM(scalar) \ - do { \ - int tmp; \ - paramIn(cp, #scalar, tmp); \ - scalar = static_cast<decltype(scalar)>(tmp); \ - } while (0) + const std::string cptDir; -#define SERIALIZE_ARRAY(member, size) \ - arrayParamOut(cp, #member, member, size) + bool find(const std::string §ion, const std::string &entry, + std::string &value); -#define UNSERIALIZE_ARRAY(member, size) \ - arrayParamIn(cp, #member, member, size) + bool findObj(const std::string §ion, const std::string &entry, + SimObject *&value); -#define SERIALIZE_CONTAINER(member) \ - arrayParamOut(cp, #member, member) -#define UNSERIALIZE_CONTAINER(member) \ - arrayParamIn(cp, #member, member) + bool entryExists(const std::string §ion, const std::string &entry); + bool sectionExists(const std::string §ion); -#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event); + // The following static functions have to do with checkpoint + // creation rather than restoration. This class makes a handy + // namespace for them though. Currently no Checkpoint object is + // created on serialization (only unserialization) so we track the + // directory name as a global. It would be nice to change this + // someday -#define UNSERIALIZE_EVENT(event) \ - do { \ - event.unserializeSection(cp, #event); \ - eventQueue()->checkpointReschedule(&event); \ - } while (0) + private: + // current directory we're serializing into. + static std::string currentDirectory; -#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj) -#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj) + public: + // Set the current directory. This function takes care of + // inserting curTick() if there's a '%d' in the argument, and + // appends a '/' if necessary. The final name is returned. + static std::string setDir(const std::string &base_name); -#define SERIALIZE_OBJPTR(objptr) paramOut(cp, #objptr, (objptr)->name()) + // Export current checkpoint directory name so other objects can + // derive filenames from it (e.g., memory). The return value is + // guaranteed to end in '/' so filenames can be directly appended. + // This function is only valid while a checkpoint is being created. + static std::string dir(); -#define UNSERIALIZE_OBJPTR(objptr) \ - do { \ - SimObject *sptr; \ - objParamIn(cp, #objptr, sptr); \ - objptr = dynamic_cast<decltype(objptr)>(sptr); \ - } while (0) + // Filename for base checkpoint file within directory. + static const char *baseFilename; +}; /** * Basic support for object serialization. @@ -368,58 +267,447 @@ class Serializable static std::stack<std::string> path; }; -void debug_serialize(const std::string &cpt_dir); +// +// The base implementations use to_number for parsing and '<<' for +// displaying, suitable for integer types. +// +template <class T> +bool +parseParam(const std::string &s, T &value) +{ + return to_number(s, value); +} +template <class T> +void +showParam(CheckpointOut &os, const T &value) +{ + os << value; +} -class CheckpointIn +// Treat 8-bit ints (chars) as ints on output, not as chars +template <> +inline void +showParam(CheckpointOut &os, const char &value) { - private: + os << (int)value; +} - IniFile *db; +template <> +inline void +showParam(CheckpointOut &os, const signed char &value) +{ + os << (int)value; +} - SimObjectResolver &objNameResolver; +template <> +inline void +showParam(CheckpointOut &os, const unsigned char &value) +{ + os << (unsigned int)value; +} - public: - CheckpointIn(const std::string &cpt_dir, SimObjectResolver &resolver); - ~CheckpointIn(); +template <> +inline bool +parseParam(const std::string &s, float &value) +{ + return to_number(s, value); +} - const std::string cptDir; +template <> +inline bool +parseParam(const std::string &s, double &value) +{ + return to_number(s, value); +} - bool find(const std::string §ion, const std::string &entry, - std::string &value); +template <> +inline bool +parseParam(const std::string &s, bool &value) +{ + return to_bool(s, value); +} - bool findObj(const std::string §ion, const std::string &entry, - SimObject *&value); +// Display bools as strings +template <> +inline void +showParam(CheckpointOut &os, const bool &value) +{ + os << (value ? "true" : "false"); +} +// String requires no processing to speak of +template <> +inline bool +parseParam(const std::string &s, std::string &value) +{ + value = s; + return true; +} - bool entryExists(const std::string §ion, const std::string &entry); - bool sectionExists(const std::string §ion); +template <class T> +void +paramOut(CheckpointOut &os, const std::string &name, const T ¶m) +{ + os << name << "="; + showParam(os, param); + os << "\n"; +} - // The following static functions have to do with checkpoint - // creation rather than restoration. This class makes a handy - // namespace for them though. Currently no Checkpoint object is - // created on serialization (only unserialization) so we track the - // directory name as a global. It would be nice to change this - // someday +template <typename T> +void +paramOut(CheckpointOut &cp, const std::string &name, const BitUnionType<T> &p) +{ + paramOut(cp, name, static_cast<BitUnionBaseType<T> >(p)); +} - private: - // current directory we're serializing into. - static std::string currentDirectory; +template <class T> +void +paramIn(CheckpointIn &cp, const std::string &name, T ¶m) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str) || !parseParam(str, param)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } +} - public: - // Set the current directory. This function takes care of - // inserting curTick() if there's a '%d' in the argument, and - // appends a '/' if necessary. The final name is returned. - static std::string setDir(const std::string &base_name); +template <typename T> +void +paramIn(CheckpointIn &cp, const std::string &name, BitUnionType<T> &p) +{ + BitUnionBaseType<T> b; + paramIn(cp, name, b); + p = b; +} - // Export current checkpoint directory name so other objects can - // derive filenames from it (e.g., memory). The return value is - // guaranteed to end in '/' so filenames can be directly appended. - // This function is only valid while a checkpoint is being created. - static std::string dir(); +template <class T> +bool +optParamIn(CheckpointIn &cp, const std::string &name, + T ¶m, bool warn = true) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str) || !parseParam(str, param)) { + if (warn) + warn("optional parameter %s:%s not present\n", section, name); + return false; + } else { + return true; + } +} - // Filename for base checkpoint file within directory. - static const char *baseFilename; -}; +template <typename T> +bool +optParamIn(CheckpointIn &cp, const std::string &name, + BitUnionType<T> &p, bool warn = true) +{ + BitUnionBaseType<T> b; + if (optParamIn(cp, name, b, warn)) { + p = b; + return true; + } else { + return false; + } +} + +template <class T> +void +arrayParamOut(CheckpointOut &os, const std::string &name, + const std::vector<T> ¶m) +{ + typename std::vector<T>::size_type size = param.size(); + os << name << "="; + if (size > 0) + showParam(os, param[0]); + for (typename std::vector<T>::size_type i = 1; i < size; ++i) { + os << " "; + showParam(os, param[i]); + } + os << "\n"; +} + +template <class T> +void +arrayParamOut(CheckpointOut &os, const std::string &name, + const std::list<T> ¶m) +{ + typename std::list<T>::const_iterator it = param.begin(); + + os << name << "="; + if (param.size() > 0) + showParam(os, *it); + it++; + while (it != param.end()) { + os << " "; + showParam(os, *it); + it++; + } + os << "\n"; +} + +template <class T> +void +arrayParamOut(CheckpointOut &os, const std::string &name, + const std::set<T> ¶m) +{ + typename std::set<T>::const_iterator it = param.begin(); + + os << name << "="; + if (param.size() > 0) + showParam(os, *it); + it++; + while (it != param.end()) { + os << " "; + showParam(os, *it); + it++; + } + os << "\n"; +} + +template <class T> +void +arrayParamOut(CheckpointOut &os, const std::string &name, + const T *param, unsigned size) +{ + os << name << "="; + if (size > 0) + showParam(os, param[0]); + for (unsigned i = 1; i < size; ++i) { + os << " "; + showParam(os, param[i]); + } + os << "\n"; +} + + +template <class T> +void +arrayParamIn(CheckpointIn &cp, const std::string &name, + T *param, unsigned size) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + + // code below stolen from VectorParam<T>::parse(). + // it would be nice to unify these somehow... + + std::vector<std::string> tokens; + + tokenize(tokens, str, ' '); + + // Need this if we were doing a vector + // value.resize(tokens.size()); + + if (tokens.size() != size) { + fatal("Array size mismatch on %s:%s'\n", section, name); + } + + for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) { + // need to parse into local variable to handle vector<bool>, + // for which operator[] returns a special reference class + // that's not the same as 'bool&', (since it's a packed + // vector) + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + std::string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param[i] = scalar_value; + } +} + +template <class T> +void +arrayParamIn(CheckpointIn &cp, const std::string &name, std::vector<T> ¶m) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + + // code below stolen from VectorParam<T>::parse(). + // it would be nice to unify these somehow... + + std::vector<std::string> tokens; + + tokenize(tokens, str, ' '); + + // Need this if we were doing a vector + // value.resize(tokens.size()); + + param.resize(tokens.size()); + + for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) { + // need to parse into local variable to handle vector<bool>, + // for which operator[] returns a special reference class + // that's not the same as 'bool&', (since it's a packed + // vector) + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + std::string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param[i] = scalar_value; + } +} + +template <class T> +void +arrayParamIn(CheckpointIn &cp, const std::string &name, std::list<T> ¶m) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + param.clear(); + + std::vector<std::string> tokens; + tokenize(tokens, str, ' '); + + for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) { + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + std::string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param.push_back(scalar_value); + } +} + +template <class T> +void +arrayParamIn(CheckpointIn &cp, const std::string &name, std::set<T> ¶m) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + param.clear(); + + std::vector<std::string> tokens; + tokenize(tokens, str, ' '); + + for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) { + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + std::string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param.insert(scalar_value); + } +} + +template <class T> +static void +arrayParamOut(CheckpointOut &cp, const std::string &name, + const BitUnionType<T> *param, unsigned size) +{ + // We copy the array into a vector. This is needed since we cannot + // directly typecast a pointer to BitUnionType<T> into a pointer + // of BitUnionBaseType<T> but we can typecast BitUnionType<T> + // to BitUnionBaseType<T> since we overloaded the typecast operator + std::vector<BitUnionBaseType<T>> bitunion_vec(param, param + size); + + arrayParamOut(cp, name, bitunion_vec); +} + +template <class T> +static void +arrayParamIn(CheckpointIn &cp, const std::string &name, + BitUnionType<T> *param, unsigned size) +{ + std::vector<BitUnionBaseType<T>> bitunion_vec(size); + + arrayParamIn(cp, name, bitunion_vec); + std::copy(bitunion_vec.begin(), bitunion_vec.end(), param); +} + +void +debug_serialize(const std::string &cpt_dir); + +void +objParamIn(CheckpointIn &cp, const std::string &name, SimObject * ¶m); + +// +// 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 'cp' and 'section'. +#define SERIALIZE_SCALAR(scalar) paramOut(cp, #scalar, scalar) + +#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, #scalar, scalar) +#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, #scalar, scalar) + +// ENUMs are like SCALARs, but we cast them to ints on the way out +#define SERIALIZE_ENUM(scalar) paramOut(cp, #scalar, (int)scalar) + +#define UNSERIALIZE_ENUM(scalar) \ + do { \ + int tmp; \ + paramIn(cp, #scalar, tmp); \ + scalar = static_cast<decltype(scalar)>(tmp); \ + } while (0) + +#define SERIALIZE_ARRAY(member, size) \ + arrayParamOut(cp, #member, member, size) + +#define UNSERIALIZE_ARRAY(member, size) \ + arrayParamIn(cp, #member, member, size) + +#define SERIALIZE_CONTAINER(member) \ + arrayParamOut(cp, #member, member) + +#define UNSERIALIZE_CONTAINER(member) \ + arrayParamIn(cp, #member, member) + +#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event); + +#define UNSERIALIZE_EVENT(event) \ + do { \ + event.unserializeSection(cp, #event); \ + eventQueue()->checkpointReschedule(&event); \ + } while (0) + +#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj) +#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj) + +#define SERIALIZE_OBJPTR(objptr) paramOut(cp, #objptr, (objptr)->name()) + +#define UNSERIALIZE_OBJPTR(objptr) \ + do { \ + SimObject *sptr; \ + objParamIn(cp, #objptr, sptr); \ + objptr = dynamic_cast<decltype(objptr)>(sptr); \ + } while (0) #endif // __SERIALIZE_HH__ |