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 &param){    os << name << "=";    showParam(os, param);    os << "\n";}template <class T>voidarrayParamOut(ostream &os, const std::string &name,              const std::vector<T> &param){    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 &section,        const std::string &name, T &param){    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 &section,             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 &section,             const std::string &name, std::vector<T> &param){    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 &section,           const std::string &name, SimObject * &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, type const &param);	\template void								\paramIn(Checkpoint *cp, const std::string &section,			\        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 &section,		\             const std::string &name, type *param, int size);           \template void								\arrayParamOut(ostream &os, const std::string &name,			\              const std::vector<type> &param);				\template void								\arrayParamIn(Checkpoint *cp, const std::string &section,		\             const std::string &name, std::vector<type> &param);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 &section = 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 &section){    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 &section){    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 &section, const std::string &entry,                 std::string &value){    return db->find(section, entry, value);}boolCheckpoint::findObj(const std::string &section, 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 &section){    return db->sectionExists(section);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?