serialize.cc
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 568 行
CC
568 行
/* * Copyright (c) 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Nathan L. Binkert * Erik G. Hallnor * Steven K. Reinhardt */#include <sys/time.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <fstream>#include <list>#include <string>#include <vector>#include "base/inifile.hh"#include "base/misc.hh"#include "base/output.hh"#include "base/str.hh"#include "base/trace.hh"#include "sim/eventq.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 <class T>boolparseParam(const string &s, T &value){ return to_number(s, value);}template <class T>voidshowParam(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 charstemplate <>voidshowParam(ostream &os, const char &value){ os << (int)value;}template <>voidshowParam(ostream &os, const unsigned char &value){ os << (unsigned int)value;}// Use sscanf() for FP types as to_number() only handles integerstemplate <>boolparseParam(const string &s, float &value){ return (sscanf(s.c_str(), "%f", &value) == 1);}template <>boolparseParam(const string &s, double &value){ return (sscanf(s.c_str(), "%lf", &value) == 1);}template <>boolparseParam(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 stringstemplate <>voidshowParam(ostream &os, const bool &value){ os << (value ? "true" : "false");}// String requires no processing to speak oftemplate <>boolparseParam(const string &s, string &value){ value = s; return true;}int Serializable::ckptMaxCount = 0;int Serializable::ckptCount = 0;int Serializable::ckptPrevCount = -1;voidSerializable::nameOut(ostream &os){ os << "\n[" << name() << "]\n";}voidSerializable::nameOut(ostream &os, const string &_name){ os << "\n[" << _name << "]\n";}template <class T>voidparamOut(ostream &os, const std::string &name, const T ¶m){ os << name << "="; showParam(os, param); os << "\n";}template <class T>voidarrayParamOut(ostream &os, const std::string &name, const std::vector<T> ¶m){ int size = param.size(); os << name << "="; if (size > 0) showParam(os, param[0]); for (int i = 1; i < size; ++i) { os << " "; showParam(os, param[i]); } os << "\n";}template <class T>voidparamIn(Checkpoint *cp, const std::string §ion, const std::string &name, T ¶m){ std::string str; if (!cp->find(section, name, str) || !parseParam(str, param)) { fatal("Can't unserialize '%s:%s'\n", section, name); }}template <class T>voidarrayParamOut(ostream &os, const std::string &name, const T *param, int size){ os << name << "="; if (size > 0) showParam(os, param[0]); for (int i = 1; i < size; ++i) { os << " "; showParam(os, param[i]); } os << "\n";}template <class T>voidarrayParamIn(Checkpoint *cp, const std::string §ion, const std::string &name, T *param, int size){ 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... 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 (int 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>voidarrayParamIn(Checkpoint *cp, const std::string §ion, const std::string &name, std::vector<T> ¶m){ 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... vector<string> tokens; tokenize(tokens, str, ' '); // Need this if we were doing a vector // value.resize(tokens.size()); param.resize(tokens.size()); for (int 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; }}voidobjParamIn(Checkpoint *cp, const std::string §ion, const std::string &name, SimObject * ¶m){ 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, 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); \template void \arrayParamOut(ostream &os, const std::string &name, \ const std::vector<type> ¶m); \template void \arrayParamIn(Checkpoint *cp, const std::string §ion, \ const std::string &name, std::vector<type> ¶m);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(string)//////////////////////////////// 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);};/// The one and only instance of the Globals class.Globals globals;const stringGlobals::name() const{ return "Globals";}voidGlobals::serialize(ostream &os){ nameOut(os); SERIALIZE_SCALAR(curTick); nameOut(os, "MainEventQueue"); mainEventQueue.serialize(os);}voidGlobals::unserialize(Checkpoint *cp){ const string §ion = name(); UNSERIALIZE_SCALAR(curTick); mainEventQueue.unserialize(cp, "MainEventQueue");}voidSerializable::serializeAll(const std::string &cpt_dir){ 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);}voidSerializable::unserializeAll(const std::string &cpt_dir){ 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);}voidSerializable::unserializeGlobals(Checkpoint *cp){ globals.unserialize(cp);}const char *Checkpoint::baseFilename = "m5.cpt";static string checkpointDirBase;voidsetCheckpointDir(const std::string &name){ checkpointDirBase = name; if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') checkpointDirBase += "/";}stringCheckpoint::dir(){ // 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;}voiddebug_serialize(const std::string &cpt_dir){ Serializable::serializeAll(cpt_dir);}//////////////////////////////////////////////////////////////////////////// SerializableClass member definitions//////////////////////////////////////////////////////////////////////////// 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 SerializableClass constructors// may be invoked before the classMap constructor.map<string,SerializableClass::CreateFunc> *SerializableClass::classMap = 0;// SerializableClass constructor: add mapping to classMapSerializableClass::SerializableClass(const string &className, CreateFunc createFunc){ if (classMap == NULL) classMap = new map<string,SerializableClass::CreateFunc>(); if ((*classMap)[className]) { cerr << "Error: simulation object class " << className << " redefined" << endl; fatal(""); } // add className --> createFunc to class map (*classMap)[className] = createFunc;}////Serializable *SerializableClass::createObject(Checkpoint *cp, const std::string §ion){ string className; if (!cp->find(section, "type", className)) { fatal("Serializable::create: no 'type' entry in section '%s'.\n", section); } CreateFunc createFunc = (*classMap)[className]; if (createFunc == NULL) { fatal("Serializable::create: no create function for class '%s'.\n", className); } Serializable *object = createFunc(cp, section); assert(object != NULL); return object;}Serializable *Serializable::create(Checkpoint *cp, const std::string §ion){ Serializable *object = SerializableClass::createObject(cp, section); object->unserialize(cp, section); return object;}Checkpoint::Checkpoint(const std::string &cpt_dir, const std::string &path) : db(new IniFile), basePath(path), cptDir(cpt_dir){ string filename = cpt_dir + "/" + Checkpoint::baseFilename; if (!db->load(filename)) { fatal("Can't load checkpoint file '%s'\n", filename); }}boolCheckpoint::find(const std::string §ion, const std::string &entry, std::string &value){ return db->find(section, entry, value);}boolCheckpoint::findObj(const std::string §ion, const std::string &entry, SimObject *&value){ string path; if (!db->find(section, entry, path)) return false; value = resolveSimObject(path); return true;}boolCheckpoint::sectionExists(const std::string §ion){ return db->sectionExists(section);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?