serialize.cc revision 8229
12SN/A/*
21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282760Sbinkertn@umich.edu * Authors: Nathan Binkert
292760Sbinkertn@umich.edu *          Erik Hallnor
302665Ssaidi@eecs.umich.edu *          Steve Reinhardt
312SN/A */
322SN/A
338229Snate@binkert.org#include <sys/stat.h>
342SN/A#include <sys/time.h>
35363SN/A#include <sys/types.h>
362SN/A
378229Snate@binkert.org#include <cerrno>
382SN/A#include <fstream>
392SN/A#include <list>
402SN/A#include <string>
412SN/A#include <vector>
422SN/A
43363SN/A#include "base/inifile.hh"
4456SN/A#include "base/misc.hh"
451388SN/A#include "base/output.hh"
46217SN/A#include "base/str.hh"
47363SN/A#include "base/trace.hh"
4856SN/A#include "sim/eventq.hh"
4956SN/A#include "sim/serialize.hh"
5056SN/A#include "sim/sim_events.hh"
511638SN/A#include "sim/sim_exit.hh"
5256SN/A#include "sim/sim_object.hh"
532SN/A
542356SN/A// For stat reset hack
552356SN/A#include "sim/stat_control.hh"
562356SN/A
572SN/Ausing namespace std;
582SN/A
594000Ssaidi@eecs.umich.eduextern SimObject *resolveSimObject(const string &);
604000Ssaidi@eecs.umich.edu
614762Snate@binkert.org//
624762Snate@binkert.org// The base implementations use to_number for parsing and '<<' for
634762Snate@binkert.org// displaying, suitable for integer types.
644762Snate@binkert.org//
654762Snate@binkert.orgtemplate <class T>
664762Snate@binkert.orgbool
674762Snate@binkert.orgparseParam(const string &s, T &value)
684762Snate@binkert.org{
694762Snate@binkert.org    return to_number(s, value);
704762Snate@binkert.org}
714762Snate@binkert.org
724762Snate@binkert.orgtemplate <class T>
734762Snate@binkert.orgvoid
744762Snate@binkert.orgshowParam(ostream &os, const T &value)
754762Snate@binkert.org{
764762Snate@binkert.org    os << value;
774762Snate@binkert.org}
784762Snate@binkert.org
794762Snate@binkert.org//
804762Snate@binkert.org// Template specializations:
814762Snate@binkert.org// - char (8-bit integer)
824762Snate@binkert.org// - floating-point types
834762Snate@binkert.org// - bool
844762Snate@binkert.org// - string
854762Snate@binkert.org//
864762Snate@binkert.org
874762Snate@binkert.org// Treat 8-bit ints (chars) as ints on output, not as chars
884762Snate@binkert.orgtemplate <>
894762Snate@binkert.orgvoid
907494Ssteve.reinhardt@amd.comshowParam(ostream &os, const char &value)
917494Ssteve.reinhardt@amd.com{
927494Ssteve.reinhardt@amd.com    os << (int)value;
937494Ssteve.reinhardt@amd.com}
947494Ssteve.reinhardt@amd.com
957494Ssteve.reinhardt@amd.com
967494Ssteve.reinhardt@amd.comtemplate <>
977494Ssteve.reinhardt@amd.comvoid
987490Ssteve.reinhardt@amd.comshowParam(ostream &os, const signed char &value)
994762Snate@binkert.org{
1004762Snate@binkert.org    os << (int)value;
1014762Snate@binkert.org}
1024762Snate@binkert.org
1034762Snate@binkert.org
1044762Snate@binkert.orgtemplate <>
1054762Snate@binkert.orgvoid
1064762Snate@binkert.orgshowParam(ostream &os, const unsigned char &value)
1074762Snate@binkert.org{
1084762Snate@binkert.org    os << (unsigned int)value;
1094762Snate@binkert.org}
1104762Snate@binkert.org
1114762Snate@binkert.org
1124762Snate@binkert.org// Use sscanf() for FP types as to_number() only handles integers
1134762Snate@binkert.orgtemplate <>
1144762Snate@binkert.orgbool
1154762Snate@binkert.orgparseParam(const string &s, float &value)
1164762Snate@binkert.org{
1174762Snate@binkert.org    return (sscanf(s.c_str(), "%f", &value) == 1);
1184762Snate@binkert.org}
1194762Snate@binkert.org
1204762Snate@binkert.orgtemplate <>
1214762Snate@binkert.orgbool
1224762Snate@binkert.orgparseParam(const string &s, double &value)
1234762Snate@binkert.org{
1244762Snate@binkert.org    return (sscanf(s.c_str(), "%lf", &value) == 1);
1254762Snate@binkert.org}
1264762Snate@binkert.org
1274762Snate@binkert.orgtemplate <>
1284762Snate@binkert.orgbool
1294762Snate@binkert.orgparseParam(const string &s, bool &value)
1304762Snate@binkert.org{
1314762Snate@binkert.org    const string &ls = to_lower(s);
1324762Snate@binkert.org
1334762Snate@binkert.org    if (ls == "true") {
1344762Snate@binkert.org        value = true;
1354762Snate@binkert.org        return true;
1364762Snate@binkert.org    }
1374762Snate@binkert.org
1384762Snate@binkert.org    if (ls == "false") {
1394762Snate@binkert.org        value = false;
1404762Snate@binkert.org        return true;
1414762Snate@binkert.org    }
1424762Snate@binkert.org
1434762Snate@binkert.org    return false;
1444762Snate@binkert.org}
1454762Snate@binkert.org
1464762Snate@binkert.org// Display bools as strings
1474762Snate@binkert.orgtemplate <>
1484762Snate@binkert.orgvoid
1494762Snate@binkert.orgshowParam(ostream &os, const bool &value)
1504762Snate@binkert.org{
1514762Snate@binkert.org    os << (value ? "true" : "false");
1524762Snate@binkert.org}
1534762Snate@binkert.org
1544762Snate@binkert.org
1554762Snate@binkert.org// String requires no processing to speak of
1564762Snate@binkert.orgtemplate <>
1574762Snate@binkert.orgbool
1584762Snate@binkert.orgparseParam(const string &s, string &value)
1594762Snate@binkert.org{
1604762Snate@binkert.org    value = s;
1614762Snate@binkert.org    return true;
1624762Snate@binkert.org}
1634762Snate@binkert.org
1642287SN/Aint Serializable::ckptMaxCount = 0;
1652287SN/Aint Serializable::ckptCount = 0;
1662287SN/Aint Serializable::ckptPrevCount = -1;
1671637SN/A
1682SN/Avoid
169395SN/ASerializable::nameOut(ostream &os)
1702SN/A{
171217SN/A    os << "\n[" << name() << "]\n";
1722SN/A}
1732SN/A
1742SN/Avoid
175395SN/ASerializable::nameOut(ostream &os, const string &_name)
1762SN/A{
177217SN/A    os << "\n[" << _name << "]\n";
1782SN/A}
1792SN/A
180217SN/Atemplate <class T>
1812SN/Avoid
1826225Snate@binkert.orgparamOut(ostream &os, const string &name, const T &param)
1832SN/A{
184217SN/A    os << name << "=";
185217SN/A    showParam(os, param);
186217SN/A    os << "\n";
1872SN/A}
1882SN/A
1894841Ssaidi@eecs.umich.edutemplate <class T>
1904841Ssaidi@eecs.umich.eduvoid
1916225Snate@binkert.orgarrayParamOut(ostream &os, const string &name, const vector<T> &param)
1924841Ssaidi@eecs.umich.edu{
1936227Snate@binkert.org    typename vector<T>::size_type size = param.size();
1944841Ssaidi@eecs.umich.edu    os << name << "=";
1954841Ssaidi@eecs.umich.edu    if (size > 0)
1964841Ssaidi@eecs.umich.edu        showParam(os, param[0]);
1976227Snate@binkert.org    for (typename vector<T>::size_type i = 1; i < size; ++i) {
1984841Ssaidi@eecs.umich.edu        os << " ";
1994841Ssaidi@eecs.umich.edu        showParam(os, param[i]);
2004841Ssaidi@eecs.umich.edu    }
2014841Ssaidi@eecs.umich.edu    os << "\n";
2024841Ssaidi@eecs.umich.edu}
2034841Ssaidi@eecs.umich.edu
2047948SAli.Saidi@ARM.comtemplate <class T>
2057948SAli.Saidi@ARM.comvoid
2067948SAli.Saidi@ARM.comarrayParamOut(ostream &os, const string &name, const list<T> &param)
2077948SAli.Saidi@ARM.com{
2087948SAli.Saidi@ARM.com    typename list<T>::const_iterator it = param.begin();
2097948SAli.Saidi@ARM.com
2107948SAli.Saidi@ARM.com    os << name << "=";
2117948SAli.Saidi@ARM.com    if (param.size() > 0)
2127948SAli.Saidi@ARM.com        showParam(os, *it);
2137948SAli.Saidi@ARM.com    it++;
2147948SAli.Saidi@ARM.com    while (it != param.end()) {
2157948SAli.Saidi@ARM.com        os << " ";
2167948SAli.Saidi@ARM.com        showParam(os, *it);
2177948SAli.Saidi@ARM.com        it++;
2187948SAli.Saidi@ARM.com    }
2197948SAli.Saidi@ARM.com    os << "\n";
2207948SAli.Saidi@ARM.com}
221217SN/A
222217SN/Atemplate <class T>
223217SN/Avoid
2246225Snate@binkert.orgparamIn(Checkpoint *cp, const string &section, const string &name, T &param)
2252SN/A{
2266225Snate@binkert.org    string str;
227237SN/A    if (!cp->find(section, name, str) || !parseParam(str, param)) {
228217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
229217SN/A    }
2302SN/A}
2312SN/A
2326820SLisa.Hsu@amd.comtemplate <class T>
2336820SLisa.Hsu@amd.combool
2346820SLisa.Hsu@amd.comoptParamIn(Checkpoint *cp, const string &section, const string &name, T &param)
2356820SLisa.Hsu@amd.com{
2366820SLisa.Hsu@amd.com    string str;
2376820SLisa.Hsu@amd.com    if (!cp->find(section, name, str) || !parseParam(str, param)) {
2386820SLisa.Hsu@amd.com        warn("optional parameter %s:%s not present\n", section, name);
2396820SLisa.Hsu@amd.com        return false;
2406820SLisa.Hsu@amd.com    } else {
2416820SLisa.Hsu@amd.com        return true;
2426820SLisa.Hsu@amd.com    }
2436820SLisa.Hsu@amd.com}
244217SN/A
245217SN/Atemplate <class T>
246217SN/Avoid
2476227Snate@binkert.orgarrayParamOut(ostream &os, const string &name, const T *param, unsigned size)
248217SN/A{
249217SN/A    os << name << "=";
250217SN/A    if (size > 0)
251217SN/A        showParam(os, param[0]);
2526227Snate@binkert.org    for (unsigned i = 1; i < size; ++i) {
253217SN/A        os << " ";
254217SN/A        showParam(os, param[i]);
255217SN/A    }
256217SN/A    os << "\n";
257217SN/A}
258217SN/A
259217SN/A
260217SN/Atemplate <class T>
261217SN/Avoid
2626225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string &section, const string &name,
2636227Snate@binkert.org             T *param, unsigned size)
264217SN/A{
2656225Snate@binkert.org    string str;
266237SN/A    if (!cp->find(section, name, str)) {
267217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
268217SN/A    }
269217SN/A
270217SN/A    // code below stolen from VectorParam<T>::parse().
271217SN/A    // it would be nice to unify these somehow...
272217SN/A
273217SN/A    vector<string> tokens;
274217SN/A
275217SN/A    tokenize(tokens, str, ' ');
276217SN/A
277217SN/A    // Need this if we were doing a vector
278217SN/A    // value.resize(tokens.size());
279217SN/A
280217SN/A    if (tokens.size() != size) {
281217SN/A        fatal("Array size mismatch on %s:%s'\n", section, name);
282217SN/A    }
283217SN/A
2846227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
285217SN/A        // need to parse into local variable to handle vector<bool>,
286217SN/A        // for which operator[] returns a special reference class
287217SN/A        // that's not the same as 'bool&', (since it's a packed
288217SN/A        // vector)
2897576SAli.Saidi@ARM.com        T scalar_value = 0;
290217SN/A        if (!parseParam(tokens[i], scalar_value)) {
291217SN/A            string err("could not parse \"");
292217SN/A
293217SN/A            err += str;
294217SN/A            err += "\"";
295217SN/A
296217SN/A            fatal(err);
297217SN/A        }
298217SN/A
299217SN/A        // assign parsed value to vector
300217SN/A        param[i] = scalar_value;
301217SN/A    }
302217SN/A}
303217SN/A
3044841Ssaidi@eecs.umich.edutemplate <class T>
3054841Ssaidi@eecs.umich.eduvoid
3066225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string &section,
3076225Snate@binkert.org             const string &name, vector<T> &param)
3084841Ssaidi@eecs.umich.edu{
3096225Snate@binkert.org    string str;
3104841Ssaidi@eecs.umich.edu    if (!cp->find(section, name, str)) {
3114841Ssaidi@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
3124841Ssaidi@eecs.umich.edu    }
3134841Ssaidi@eecs.umich.edu
3144841Ssaidi@eecs.umich.edu    // code below stolen from VectorParam<T>::parse().
3154841Ssaidi@eecs.umich.edu    // it would be nice to unify these somehow...
3164841Ssaidi@eecs.umich.edu
3174841Ssaidi@eecs.umich.edu    vector<string> tokens;
3184841Ssaidi@eecs.umich.edu
3194841Ssaidi@eecs.umich.edu    tokenize(tokens, str, ' ');
3204841Ssaidi@eecs.umich.edu
3214841Ssaidi@eecs.umich.edu    // Need this if we were doing a vector
3224841Ssaidi@eecs.umich.edu    // value.resize(tokens.size());
3234841Ssaidi@eecs.umich.edu
3244841Ssaidi@eecs.umich.edu    param.resize(tokens.size());
3254841Ssaidi@eecs.umich.edu
3266227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
3274841Ssaidi@eecs.umich.edu        // need to parse into local variable to handle vector<bool>,
3284841Ssaidi@eecs.umich.edu        // for which operator[] returns a special reference class
3294841Ssaidi@eecs.umich.edu        // that's not the same as 'bool&', (since it's a packed
3304841Ssaidi@eecs.umich.edu        // vector)
3317576SAli.Saidi@ARM.com        T scalar_value = 0;
3324841Ssaidi@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
3334841Ssaidi@eecs.umich.edu            string err("could not parse \"");
3344841Ssaidi@eecs.umich.edu
3354841Ssaidi@eecs.umich.edu            err += str;
3364841Ssaidi@eecs.umich.edu            err += "\"";
3374841Ssaidi@eecs.umich.edu
3384841Ssaidi@eecs.umich.edu            fatal(err);
3394841Ssaidi@eecs.umich.edu        }
3404841Ssaidi@eecs.umich.edu
3414841Ssaidi@eecs.umich.edu        // assign parsed value to vector
3424841Ssaidi@eecs.umich.edu        param[i] = scalar_value;
3434841Ssaidi@eecs.umich.edu    }
3444841Ssaidi@eecs.umich.edu}
3454841Ssaidi@eecs.umich.edu
3467948SAli.Saidi@ARM.comtemplate <class T>
3477948SAli.Saidi@ARM.comvoid
3487948SAli.Saidi@ARM.comarrayParamIn(Checkpoint *cp, const string &section,
3497948SAli.Saidi@ARM.com             const string &name, list<T> &param)
3507948SAli.Saidi@ARM.com{
3517948SAli.Saidi@ARM.com    string str;
3527948SAli.Saidi@ARM.com    if (!cp->find(section, name, str)) {
3537948SAli.Saidi@ARM.com        fatal("Can't unserialize '%s:%s'\n", section, name);
3547948SAli.Saidi@ARM.com    }
3557948SAli.Saidi@ARM.com    param.clear();
3567948SAli.Saidi@ARM.com
3577948SAli.Saidi@ARM.com    vector<string> tokens;
3587948SAli.Saidi@ARM.com    tokenize(tokens, str, ' ');
3597948SAli.Saidi@ARM.com
3607948SAli.Saidi@ARM.com    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
3617948SAli.Saidi@ARM.com        T scalar_value = 0;
3627948SAli.Saidi@ARM.com        if (!parseParam(tokens[i], scalar_value)) {
3637948SAli.Saidi@ARM.com            string err("could not parse \"");
3647948SAli.Saidi@ARM.com
3657948SAli.Saidi@ARM.com            err += str;
3667948SAli.Saidi@ARM.com            err += "\"";
3677948SAli.Saidi@ARM.com
3687948SAli.Saidi@ARM.com            fatal(err);
3697948SAli.Saidi@ARM.com        }
3707948SAli.Saidi@ARM.com
3717948SAli.Saidi@ARM.com        // assign parsed value to vector
3727948SAli.Saidi@ARM.com        param.push_back(scalar_value);
3737948SAli.Saidi@ARM.com    }
3747948SAli.Saidi@ARM.com}
3757948SAli.Saidi@ARM.com
3767948SAli.Saidi@ARM.com
377237SN/Avoid
3786225Snate@binkert.orgobjParamIn(Checkpoint *cp, const string &section,
3796225Snate@binkert.org           const string &name, SimObject * &param)
380237SN/A{
381237SN/A    if (!cp->findObj(section, name, param)) {
382237SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
383237SN/A    }
384237SN/A}
385237SN/A
386237SN/A
3875543Ssaidi@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type)                               \
3885543Ssaidi@eecs.umich.edutemplate void                                                           \
3896225Snate@binkert.orgparamOut(ostream &os, const string &name, type const &param);           \
3905543Ssaidi@eecs.umich.edutemplate void                                                           \
3916225Snate@binkert.orgparamIn(Checkpoint *cp, const string &section,                          \
3926225Snate@binkert.org        const string &name, type & param);                              \
3936820SLisa.Hsu@amd.comtemplate bool                                                           \
3946820SLisa.Hsu@amd.comoptParamIn(Checkpoint *cp, const string &section,                       \
3956820SLisa.Hsu@amd.com        const string &name, type & param);                              \
3965543Ssaidi@eecs.umich.edutemplate void                                                           \
3976225Snate@binkert.orgarrayParamOut(ostream &os, const string &name,                          \
3986227Snate@binkert.org              type const *param, unsigned size);                        \
3995543Ssaidi@eecs.umich.edutemplate void                                                           \
4006225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string &section,                     \
4016227Snate@binkert.org             const string &name, type *param, unsigned size);           \
4025543Ssaidi@eecs.umich.edutemplate void                                                           \
4036225Snate@binkert.orgarrayParamOut(ostream &os, const string &name,                          \
4046225Snate@binkert.org              const vector<type> &param);                               \
4055543Ssaidi@eecs.umich.edutemplate void                                                           \
4066225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string &section,                     \
4077948SAli.Saidi@ARM.com             const string &name, vector<type> &param);                  \
4087948SAli.Saidi@ARM.comtemplate void                                                           \
4097948SAli.Saidi@ARM.comarrayParamOut(ostream &os, const string &name,                          \
4107948SAli.Saidi@ARM.com              const list<type> &param);                                 \
4117948SAli.Saidi@ARM.comtemplate void                                                           \
4127948SAli.Saidi@ARM.comarrayParamIn(Checkpoint *cp, const string &section,                     \
4137948SAli.Saidi@ARM.com             const string &name, list<type> &param);
414217SN/A
4157494Ssteve.reinhardt@amd.comINSTANTIATE_PARAM_TEMPLATES(char)
4161642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char)
4171642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char)
4181642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short)
4191642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short)
4201642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int)
4211642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int)
4221642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long)
4231642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long)
4241642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long)
4251642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long)
426219SN/AINSTANTIATE_PARAM_TEMPLATES(bool)
4275992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(float)
4285992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(double)
429217SN/AINSTANTIATE_PARAM_TEMPLATES(string)
430217SN/A
431217SN/A
432395SN/A/////////////////////////////
433395SN/A
434395SN/A/// Container for serializing global variables (not associated with
435395SN/A/// any serialized object).
436395SN/Aclass Globals : public Serializable
4372SN/A{
438395SN/A  public:
439512SN/A    const string name() const;
440510SN/A    void serialize(ostream &os);
441395SN/A    void unserialize(Checkpoint *cp);
442395SN/A};
4432SN/A
444395SN/A/// The one and only instance of the Globals class.
445395SN/AGlobals globals;
4462SN/A
447512SN/Aconst string
448395SN/AGlobals::name() const
4492SN/A{
450395SN/A    return "Globals";
4512SN/A}
4522SN/A
4532SN/Avoid
454510SN/AGlobals::serialize(ostream &os)
4552SN/A{
456395SN/A    nameOut(os);
4577864Ssteve.reinhardt@amd.com    paramOut(os, "curTick", curTick());
458395SN/A
459395SN/A    nameOut(os, "MainEventQueue");
460395SN/A    mainEventQueue.serialize(os);
4612SN/A}
4622SN/A
4632SN/Avoid
464395SN/AGlobals::unserialize(Checkpoint *cp)
4652SN/A{
466395SN/A    const string &section = name();
4677823Ssteve.reinhardt@amd.com    Tick tick;
4687823Ssteve.reinhardt@amd.com    paramIn(cp, section, "curTick", tick);
4697823Ssteve.reinhardt@amd.com    curTick(tick);
4702SN/A
471395SN/A    mainEventQueue.unserialize(cp, "MainEventQueue");
4722SN/A}
4732SN/A
4745739Snate@binkert.orgSerializable::Serializable()
4755739Snate@binkert.org{
4765739Snate@binkert.org}
4775739Snate@binkert.org
4785739Snate@binkert.orgSerializable::~Serializable()
4795739Snate@binkert.org{
4805739Snate@binkert.org}
4815739Snate@binkert.org
4825739Snate@binkert.orgvoid
4836225Snate@binkert.orgSerializable::serialize(ostream &os)
4845739Snate@binkert.org{
4855739Snate@binkert.org}
4865739Snate@binkert.org
4875739Snate@binkert.orgvoid
4886225Snate@binkert.orgSerializable::unserialize(Checkpoint *cp, const string &section)
4895739Snate@binkert.org{
4905739Snate@binkert.org}
4915739Snate@binkert.org
4922SN/Avoid
4936225Snate@binkert.orgSerializable::serializeAll(const string &cpt_dir)
4942SN/A{
4957491Ssteve.reinhardt@amd.com    string dir = Checkpoint::setDir(cpt_dir);
496363SN/A    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
497449SN/A            fatal("couldn't mkdir %s\n", dir);
498363SN/A
499449SN/A    string cpt_file = dir + Checkpoint::baseFilename;
500395SN/A    ofstream outstream(cpt_file.c_str());
5012SN/A    time_t t = time(NULL);
5025581Ssaidi@eecs.umich.edu    if (!outstream.is_open())
5035581Ssaidi@eecs.umich.edu        fatal("Unable to open file %s for writing\n", cpt_file.c_str());
5046818SLisa.Hsu@amd.com    outstream << "## checkpoint generated: " << ctime(&t);
5052SN/A
506395SN/A    globals.serialize(outstream);
507395SN/A    SimObject::serializeAll(outstream);
508395SN/A}
5092SN/A
5102797Sktlim@umich.eduvoid
511395SN/ASerializable::unserializeGlobals(Checkpoint *cp)
512395SN/A{
513395SN/A    globals.unserialize(cp);
514395SN/A}
5152SN/A
5162SN/Avoid
5176225Snate@binkert.orgdebug_serialize(const string &cpt_dir)
5182SN/A{
5192868Sktlim@umich.edu    Serializable::serializeAll(cpt_dir);
5202SN/A}
5212SN/A
5222SN/A
5232SN/A////////////////////////////////////////////////////////////////////////
5242SN/A//
525395SN/A// SerializableClass member definitions
5262SN/A//
5272SN/A////////////////////////////////////////////////////////////////////////
5282SN/A
529395SN/A// Map of class names to SerializableBuilder creation functions.
5302SN/A// Need to make this a pointer so we can force initialization on the
531395SN/A// first reference; otherwise, some SerializableClass constructors
5322SN/A// may be invoked before the classMap constructor.
5336225Snate@binkert.orgmap<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0;
5342SN/A
535395SN/A// SerializableClass constructor: add mapping to classMap
536395SN/ASerializableClass::SerializableClass(const string &className,
5376225Snate@binkert.org                                     CreateFunc createFunc)
5382SN/A{
5392SN/A    if (classMap == NULL)
5406225Snate@binkert.org        classMap = new map<string, SerializableClass::CreateFunc>();
5412SN/A
5422SN/A    if ((*classMap)[className])
5436225Snate@binkert.org        fatal("Error: simulation object class %s redefined\n", className);
5442SN/A
5452SN/A    // add className --> createFunc to class map
5462SN/A    (*classMap)[className] = createFunc;
5472SN/A}
5482SN/A
5492SN/A//
5502SN/A//
551395SN/ASerializable *
5526225Snate@binkert.orgSerializableClass::createObject(Checkpoint *cp, const string &section)
5532SN/A{
554237SN/A    string className;
5552SN/A
556237SN/A    if (!cp->find(section, "type", className)) {
557395SN/A        fatal("Serializable::create: no 'type' entry in section '%s'.\n",
558237SN/A              section);
5592SN/A    }
5602SN/A
561237SN/A    CreateFunc createFunc = (*classMap)[className];
562237SN/A
563237SN/A    if (createFunc == NULL) {
564395SN/A        fatal("Serializable::create: no create function for class '%s'.\n",
565237SN/A              className);
5662SN/A    }
5672SN/A
568395SN/A    Serializable *object = createFunc(cp, section);
5692SN/A
5702SN/A    assert(object != NULL);
5712SN/A
5722SN/A    return object;
5732SN/A}
5742SN/A
575237SN/A
576395SN/ASerializable *
5776225Snate@binkert.orgSerializable::create(Checkpoint *cp, const string &section)
578237SN/A{
579395SN/A    Serializable *object = SerializableClass::createObject(cp, section);
580237SN/A    object->unserialize(cp, section);
581237SN/A    return object;
582237SN/A}
583237SN/A
584237SN/A
5857491Ssteve.reinhardt@amd.comconst char *Checkpoint::baseFilename = "m5.cpt";
5867491Ssteve.reinhardt@amd.com
5877491Ssteve.reinhardt@amd.comstring Checkpoint::currentDirectory;
5887491Ssteve.reinhardt@amd.com
5897491Ssteve.reinhardt@amd.comstring
5907491Ssteve.reinhardt@amd.comCheckpoint::setDir(const string &name)
5917491Ssteve.reinhardt@amd.com{
5927823Ssteve.reinhardt@amd.com    // use csprintf to insert curTick() into directory name if it
5937491Ssteve.reinhardt@amd.com    // appears to have a format placeholder in it.
5947491Ssteve.reinhardt@amd.com    currentDirectory = (name.find("%") != string::npos) ?
5957823Ssteve.reinhardt@amd.com        csprintf(name, curTick()) : name;
5967491Ssteve.reinhardt@amd.com    if (currentDirectory[currentDirectory.size() - 1] != '/')
5977491Ssteve.reinhardt@amd.com        currentDirectory += "/";
5987491Ssteve.reinhardt@amd.com    return currentDirectory;
5997491Ssteve.reinhardt@amd.com}
6007491Ssteve.reinhardt@amd.com
6017491Ssteve.reinhardt@amd.comstring
6027491Ssteve.reinhardt@amd.comCheckpoint::dir()
6037491Ssteve.reinhardt@amd.com{
6047491Ssteve.reinhardt@amd.com    return currentDirectory;
6057491Ssteve.reinhardt@amd.com}
6067491Ssteve.reinhardt@amd.com
6077491Ssteve.reinhardt@amd.com
6087491Ssteve.reinhardt@amd.comCheckpoint::Checkpoint(const string &cpt_dir)
6097532Ssteve.reinhardt@amd.com    : db(new IniFile), cptDir(setDir(cpt_dir))
610237SN/A{
6117532Ssteve.reinhardt@amd.com    string filename = cptDir + "/" + Checkpoint::baseFilename;
612237SN/A    if (!db->load(filename)) {
613237SN/A        fatal("Can't load checkpoint file '%s'\n", filename);
614237SN/A    }
615237SN/A}
616237SN/A
617237SN/A
618237SN/Abool
6196225Snate@binkert.orgCheckpoint::find(const string &section, const string &entry, string &value)
620237SN/A{
621237SN/A    return db->find(section, entry, value);
622237SN/A}
623237SN/A
624237SN/A
625237SN/Abool
6266225Snate@binkert.orgCheckpoint::findObj(const string &section, const string &entry,
6274000Ssaidi@eecs.umich.edu                    SimObject *&value)
628237SN/A{
629237SN/A    string path;
630237SN/A
631237SN/A    if (!db->find(section, entry, path))
632237SN/A        return false;
633237SN/A
6344000Ssaidi@eecs.umich.edu    value = resolveSimObject(path);
6354000Ssaidi@eecs.umich.edu    return true;
636237SN/A}
637304SN/A
638304SN/A
639304SN/Abool
6406225Snate@binkert.orgCheckpoint::sectionExists(const string &section)
641304SN/A{
642304SN/A    return db->sectionExists(section);
643304SN/A}
644