X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsim%2Fserialize.cc;h=aa343d0e9c2ed7569574ad866f0fbef44d414754;hb=df9f99567d43c9dfcecc625dce748c561699b307;hp=6a1d084b7b4e7d25540f6ad35581a0ffe3e74076;hpb=0b0cb2bca71acdab4a30acc639509030631f9dfd;p=gem5.git diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 6a1d084b7..aa343d0e9 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -46,14 +46,121 @@ #include "base/str.hh" #include "base/trace.hh" #include "sim/eventq.hh" -#include "sim/param.hh" #include "sim/serialize.hh" #include "sim/sim_events.hh" #include "sim/sim_exit.hh" #include "sim/sim_object.hh" +// For stat reset hack +#include "sim/stat_control.hh" + using namespace std; +extern SimObject *resolveSimObject(const string &); + +// +// The base implementations use to_number for parsing and '<<' for +// displaying, suitable for integer types. +// +template +bool +parseParam(const string &s, T &value) +{ + return to_number(s, value); +} + +template +void +showParam(ostream &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(ostream &os, const char &value) +{ + os << (int)value; +} + + +template <> +void +showParam(ostream &os, const signed char &value) +{ + os << (int)value; +} + + +template <> +void +showParam(ostream &os, const unsigned char &value) +{ + os << (unsigned int)value; +} + + +// Use sscanf() for FP types as to_number() only handles integers +template <> +bool +parseParam(const string &s, float &value) +{ + return (sscanf(s.c_str(), "%f", &value) == 1); +} + +template <> +bool +parseParam(const string &s, double &value) +{ + return (sscanf(s.c_str(), "%lf", &value) == 1); +} + +template <> +bool +parseParam(const string &s, bool &value) +{ + const string &ls = to_lower(s); + + if (ls == "true") { + value = true; + return true; + } + + if (ls == "false") { + value = false; + return true; + } + + return false; +} + +// Display bools as strings +template <> +void +showParam(ostream &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; @@ -72,35 +179,60 @@ Serializable::nameOut(ostream &os, const string &_name) template void -paramOut(ostream &os, const std::string &name, const T ¶m) +paramOut(ostream &os, const string &name, const T ¶m) { os << name << "="; showParam(os, param); os << "\n"; } +template +void +arrayParamOut(ostream &os, const string &name, const vector ¶m) +{ + typename vector::size_type size = param.size(); + os << name << "="; + if (size > 0) + showParam(os, param[0]); + for (typename vector::size_type i = 1; i < size; ++i) { + os << " "; + showParam(os, param[i]); + } + os << "\n"; +} + template void -paramIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T ¶m) +paramIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) { - std::string str; + string str; if (!cp->find(section, name, str) || !parseParam(str, param)) { fatal("Can't unserialize '%s:%s'\n", section, name); } } +template +bool +optParamIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) +{ + string str; + if (!cp->find(section, name, str) || !parseParam(str, param)) { + warn("optional parameter %s:%s not present\n", section, name); + return false; + } else { + return true; + } +} template void -arrayParamOut(ostream &os, const std::string &name, - const T *param, int size) +arrayParamOut(ostream &os, const string &name, const T *param, unsigned size) { os << name << "="; if (size > 0) showParam(os, param[0]); - for (int i = 1; i < size; ++i) { + for (unsigned i = 1; i < size; ++i) { os << " "; showParam(os, param[i]); } @@ -110,10 +242,10 @@ arrayParamOut(ostream &os, const std::string &name, template void -arrayParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T *param, int size) +arrayParamIn(Checkpoint *cp, const string §ion, const string &name, + T *param, unsigned size) { - std::string str; + string str; if (!cp->find(section, name, str)) { fatal("Can't unserialize '%s:%s'\n", section, name); } @@ -132,12 +264,12 @@ arrayParamIn(Checkpoint *cp, const std::string §ion, fatal("Array size mismatch on %s:%s'\n", section, name); } - for (int i = 0; i < tokens.size(); i++) { + for (vector::size_type i = 0; i < tokens.size(); i++) { // need to parse into local variable to handle vector, // for which operator[] returns a special reference class // that's not the same as 'bool&', (since it's a packed // vector) - T scalar_value; + T scalar_value = 0; if (!parseParam(tokens[i], scalar_value)) { string err("could not parse \""); @@ -152,10 +284,51 @@ arrayParamIn(Checkpoint *cp, const std::string §ion, } } +template +void +arrayParamIn(Checkpoint *cp, const string §ion, + const string &name, vector ¶m) +{ + string str; + if (!cp->find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + + // code below stolen from VectorParam::parse(). + // it would be nice to unify these somehow... + + vector tokens; + + tokenize(tokens, str, ' '); + + // Need this if we were doing a vector + // value.resize(tokens.size()); + + param.resize(tokens.size()); + + for (vector::size_type i = 0; i < tokens.size(); i++) { + // need to parse into local variable to handle vector, + // for which operator[] returns a special reference class + // that's not the same as 'bool&', (since it's a packed + // vector) + T scalar_value = 0; + 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; + } +} void -objParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, Serializable * ¶m) +objParamIn(Checkpoint *cp, const string §ion, + const string &name, SimObject * ¶m) { if (!cp->findObj(section, name, param)) { fatal("Can't unserialize '%s:%s'\n", section, name); @@ -163,19 +336,29 @@ objParamIn(Checkpoint *cp, const std::string §ion, } -#define INSTANTIATE_PARAM_TEMPLATES(type) \ -template void \ -paramOut(ostream &os, const std::string &name, type const ¶m); \ -template void \ -paramIn(Checkpoint *cp, const std::string §ion, \ - const std::string &name, type & param); \ -template void \ -arrayParamOut(ostream &os, const std::string &name, \ - type const *param, int size); \ -template void \ -arrayParamIn(Checkpoint *cp, const std::string §ion, \ - const std::string &name, type *param, int size); - +#define INSTANTIATE_PARAM_TEMPLATES(type) \ +template void \ +paramOut(ostream &os, const string &name, type const ¶m); \ +template void \ +paramIn(Checkpoint *cp, const string §ion, \ + const string &name, type & param); \ +template bool \ +optParamIn(Checkpoint *cp, const string §ion, \ + const string &name, type & param); \ +template void \ +arrayParamOut(ostream &os, const string &name, \ + type const *param, unsigned size); \ +template void \ +arrayParamIn(Checkpoint *cp, const string §ion, \ + const string &name, type *param, unsigned size); \ +template void \ +arrayParamOut(ostream &os, const string &name, \ + const vector ¶m); \ +template void \ +arrayParamIn(Checkpoint *cp, const string §ion, \ + const string &name, vector ¶m); + +INSTANTIATE_PARAM_TEMPLATES(char) INSTANTIATE_PARAM_TEMPLATES(signed char) INSTANTIATE_PARAM_TEMPLATES(unsigned char) INSTANTIATE_PARAM_TEMPLATES(signed short) @@ -187,6 +370,8 @@ 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) @@ -230,68 +415,50 @@ Globals::unserialize(Checkpoint *cp) mainEventQueue.unserialize(cp, "MainEventQueue"); } -void -Serializable::serializeAll(const std::string &cpt_dir) +Serializable::Serializable() { - setCheckpointDir(cpt_dir); - string dir = Checkpoint::dir(); - if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) - fatal("couldn't mkdir %s\n", dir); - - string cpt_file = dir + Checkpoint::baseFilename; - ofstream outstream(cpt_file.c_str()); - time_t t = time(NULL); - outstream << "// checkpoint generated: " << ctime(&t); +} - globals.serialize(outstream); - SimObject::serializeAll(outstream); +Serializable::~Serializable() +{ } void -Serializable::unserializeAll(const std::string &cpt_dir) +Serializable::serialize(ostream &os) { - setCheckpointDir(cpt_dir); - string dir = Checkpoint::dir(); - string cpt_file = dir + Checkpoint::baseFilename; - string section = ""; - - DPRINTFR(Config, "Loading checkpoint dir '%s'\n", - dir); - Checkpoint *cp = new Checkpoint(dir, section); - unserializeGlobals(cp); - - SimObject::unserializeAll(cp); } void -Serializable::unserializeGlobals(Checkpoint *cp) +Serializable::unserialize(Checkpoint *cp, const string §ion) { - globals.unserialize(cp); } -const char *Checkpoint::baseFilename = "m5.cpt"; - -static string checkpointDirBase; - void -setCheckpointDir(const std::string &name) +Serializable::serializeAll(const string &cpt_dir) { - checkpointDirBase = name; - if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') - checkpointDirBase += "/"; + string dir = Checkpoint::setDir(cpt_dir); + if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) + fatal("couldn't mkdir %s\n", dir); + + string cpt_file = dir + Checkpoint::baseFilename; + ofstream outstream(cpt_file.c_str()); + time_t t = time(NULL); + if (!outstream.is_open()) + fatal("Unable to open file %s for writing\n", cpt_file.c_str()); + outstream << "## checkpoint generated: " << ctime(&t); + + globals.serialize(outstream); + SimObject::serializeAll(outstream); } -string -Checkpoint::dir() +void +Serializable::unserializeGlobals(Checkpoint *cp) { - // 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; + globals.unserialize(cp); } void -debug_serialize(const std::string &cpt_dir) +debug_serialize(const string &cpt_dir) { Serializable::serializeAll(cpt_dir); } @@ -307,32 +474,26 @@ debug_serialize(const std::string &cpt_dir) // Need to make this a pointer so we can force initialization on the // first reference; otherwise, some SerializableClass constructors // may be invoked before the classMap constructor. -map *SerializableClass::classMap = 0; +map *SerializableClass::classMap = 0; // SerializableClass constructor: add mapping to classMap SerializableClass::SerializableClass(const string &className, - CreateFunc createFunc) + CreateFunc createFunc) { if (classMap == NULL) - classMap = new map(); + classMap = new map(); if ((*classMap)[className]) - { - cerr << "Error: simulation object class " << className << " redefined" - << endl; - fatal(""); - } + fatal("Error: simulation object class %s redefined\n", className); // add className --> createFunc to class map (*classMap)[className] = createFunc; } - // // Serializable * -SerializableClass::createObject(Checkpoint *cp, - const std::string §ion) +SerializableClass::createObject(Checkpoint *cp, const string §ion) { string className; @@ -357,7 +518,7 @@ SerializableClass::createObject(Checkpoint *cp, Serializable * -Serializable::create(Checkpoint *cp, const std::string §ion) +Serializable::create(Checkpoint *cp, const string §ion) { Serializable *object = SerializableClass::createObject(cp, section); object->unserialize(cp, section); @@ -365,10 +526,33 @@ Serializable::create(Checkpoint *cp, const std::string §ion) } -Checkpoint::Checkpoint(const std::string &cpt_dir, const std::string &path) - : db(new IniFile), basePath(path), cptDir(cpt_dir) +const char *Checkpoint::baseFilename = "m5.cpt"; + +string Checkpoint::currentDirectory; + +string +Checkpoint::setDir(const string &name) { - string filename = cpt_dir + "/" + Checkpoint::baseFilename; + // use csprintf to insert curTick into directory name if it + // appears to have a format placeholder in it. + currentDirectory = (name.find("%") != string::npos) ? + csprintf(name, curTick) : name; + if (currentDirectory[currentDirectory.size() - 1] != '/') + currentDirectory += "/"; + return currentDirectory; +} + +string +Checkpoint::dir() +{ + return currentDirectory; +} + + +Checkpoint::Checkpoint(const string &cpt_dir) + : db(new IniFile), cptDir(setDir(cpt_dir)) +{ + string filename = cptDir + "/" + Checkpoint::baseFilename; if (!db->load(filename)) { fatal("Can't load checkpoint file '%s'\n", filename); } @@ -376,31 +560,28 @@ Checkpoint::Checkpoint(const std::string &cpt_dir, const std::string &path) bool -Checkpoint::find(const std::string §ion, const std::string &entry, - std::string &value) +Checkpoint::find(const string §ion, const string &entry, string &value) { return db->find(section, entry, value); } bool -Checkpoint::findObj(const std::string §ion, const std::string &entry, - Serializable *&value) +Checkpoint::findObj(const string §ion, const string &entry, + SimObject *&value) { string path; if (!db->find(section, entry, path)) return false; - if ((value = objMap[path]) != NULL) - return true; - - return false; + value = resolveSimObject(path); + return true; } bool -Checkpoint::sectionExists(const std::string §ion) +Checkpoint::sectionExists(const string §ion) { return db->sectionExists(section); }