serialize.cc revision 7491
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
332SN/A#include <sys/time.h>
34363SN/A#include <sys/types.h>
35363SN/A#include <sys/stat.h>
361354SN/A#include <errno.h>
372SN/A
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
907490Ssteve.reinhardt@amd.comshowParam(ostream &os, const signed char &value)
914762Snate@binkert.org{
924762Snate@binkert.org    os << (int)value;
934762Snate@binkert.org}
944762Snate@binkert.org
954762Snate@binkert.org
964762Snate@binkert.orgtemplate <>
974762Snate@binkert.orgvoid
984762Snate@binkert.orgshowParam(ostream &os, const unsigned char &value)
994762Snate@binkert.org{
1004762Snate@binkert.org    os << (unsigned int)value;
1014762Snate@binkert.org}
1024762Snate@binkert.org
1034762Snate@binkert.org
1044762Snate@binkert.org// Use sscanf() for FP types as to_number() only handles integers
1054762Snate@binkert.orgtemplate <>
1064762Snate@binkert.orgbool
1074762Snate@binkert.orgparseParam(const string &s, float &value)
1084762Snate@binkert.org{
1094762Snate@binkert.org    return (sscanf(s.c_str(), "%f", &value) == 1);
1104762Snate@binkert.org}
1114762Snate@binkert.org
1124762Snate@binkert.orgtemplate <>
1134762Snate@binkert.orgbool
1144762Snate@binkert.orgparseParam(const string &s, double &value)
1154762Snate@binkert.org{
1164762Snate@binkert.org    return (sscanf(s.c_str(), "%lf", &value) == 1);
1174762Snate@binkert.org}
1184762Snate@binkert.org
1194762Snate@binkert.orgtemplate <>
1204762Snate@binkert.orgbool
1214762Snate@binkert.orgparseParam(const string &s, bool &value)
1224762Snate@binkert.org{
1234762Snate@binkert.org    const string &ls = to_lower(s);
1244762Snate@binkert.org
1254762Snate@binkert.org    if (ls == "true") {
1264762Snate@binkert.org        value = true;
1274762Snate@binkert.org        return true;
1284762Snate@binkert.org    }
1294762Snate@binkert.org
1304762Snate@binkert.org    if (ls == "false") {
1314762Snate@binkert.org        value = false;
1324762Snate@binkert.org        return true;
1334762Snate@binkert.org    }
1344762Snate@binkert.org
1354762Snate@binkert.org    return false;
1364762Snate@binkert.org}
1374762Snate@binkert.org
1384762Snate@binkert.org// Display bools as strings
1394762Snate@binkert.orgtemplate <>
1404762Snate@binkert.orgvoid
1414762Snate@binkert.orgshowParam(ostream &os, const bool &value)
1424762Snate@binkert.org{
1434762Snate@binkert.org    os << (value ? "true" : "false");
1444762Snate@binkert.org}
1454762Snate@binkert.org
1464762Snate@binkert.org
1474762Snate@binkert.org// String requires no processing to speak of
1484762Snate@binkert.orgtemplate <>
1494762Snate@binkert.orgbool
1504762Snate@binkert.orgparseParam(const string &s, string &value)
1514762Snate@binkert.org{
1524762Snate@binkert.org    value = s;
1534762Snate@binkert.org    return true;
1544762Snate@binkert.org}
1554762Snate@binkert.org
1562287SN/Aint Serializable::ckptMaxCount = 0;
1572287SN/Aint Serializable::ckptCount = 0;
1582287SN/Aint Serializable::ckptPrevCount = -1;
1591637SN/A
1602SN/Avoid
161395SN/ASerializable::nameOut(ostream &os)
1622SN/A{
163217SN/A    os << "\n[" << name() << "]\n";
1642SN/A}
1652SN/A
1662SN/Avoid
167395SN/ASerializable::nameOut(ostream &os, const string &_name)
1682SN/A{
169217SN/A    os << "\n[" << _name << "]\n";
1702SN/A}
1712SN/A
172217SN/Atemplate <class T>
1732SN/Avoid
1746225Snate@binkert.orgparamOut(ostream &os, const string &name, const T &param)
1752SN/A{
176217SN/A    os << name << "=";
177217SN/A    showParam(os, param);
178217SN/A    os << "\n";
1792SN/A}
1802SN/A
1814841Ssaidi@eecs.umich.edutemplate <class T>
1824841Ssaidi@eecs.umich.eduvoid
1836225Snate@binkert.orgarrayParamOut(ostream &os, const string &name, const vector<T> &param)
1844841Ssaidi@eecs.umich.edu{
1856227Snate@binkert.org    typename vector<T>::size_type size = param.size();
1864841Ssaidi@eecs.umich.edu    os << name << "=";
1874841Ssaidi@eecs.umich.edu    if (size > 0)
1884841Ssaidi@eecs.umich.edu        showParam(os, param[0]);
1896227Snate@binkert.org    for (typename vector<T>::size_type i = 1; i < size; ++i) {
1904841Ssaidi@eecs.umich.edu        os << " ";
1914841Ssaidi@eecs.umich.edu        showParam(os, param[i]);
1924841Ssaidi@eecs.umich.edu    }
1934841Ssaidi@eecs.umich.edu    os << "\n";
1944841Ssaidi@eecs.umich.edu}
1954841Ssaidi@eecs.umich.edu
196217SN/A
197217SN/Atemplate <class T>
198217SN/Avoid
1996225Snate@binkert.orgparamIn(Checkpoint *cp, const string &section, const string &name, T &param)
2002SN/A{
2016225Snate@binkert.org    string str;
202237SN/A    if (!cp->find(section, name, str) || !parseParam(str, param)) {
203217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
204217SN/A    }
2052SN/A}
2062SN/A
2076820SLisa.Hsu@amd.comtemplate <class T>
2086820SLisa.Hsu@amd.combool
2096820SLisa.Hsu@amd.comoptParamIn(Checkpoint *cp, const string &section, const string &name, T &param)
2106820SLisa.Hsu@amd.com{
2116820SLisa.Hsu@amd.com    string str;
2126820SLisa.Hsu@amd.com    if (!cp->find(section, name, str) || !parseParam(str, param)) {
2136820SLisa.Hsu@amd.com        warn("optional parameter %s:%s not present\n", section, name);
2146820SLisa.Hsu@amd.com        return false;
2156820SLisa.Hsu@amd.com    } else {
2166820SLisa.Hsu@amd.com        return true;
2176820SLisa.Hsu@amd.com    }
2186820SLisa.Hsu@amd.com}
219217SN/A
220217SN/Atemplate <class T>
221217SN/Avoid
2226227Snate@binkert.orgarrayParamOut(ostream &os, const string &name, const T *param, unsigned size)
223217SN/A{
224217SN/A    os << name << "=";
225217SN/A    if (size > 0)
226217SN/A        showParam(os, param[0]);
2276227Snate@binkert.org    for (unsigned i = 1; i < size; ++i) {
228217SN/A        os << " ";
229217SN/A        showParam(os, param[i]);
230217SN/A    }
231217SN/A    os << "\n";
232217SN/A}
233217SN/A
234217SN/A
235217SN/Atemplate <class T>
236217SN/Avoid
2376225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string &section, const string &name,
2386227Snate@binkert.org             T *param, unsigned size)
239217SN/A{
2406225Snate@binkert.org    string str;
241237SN/A    if (!cp->find(section, name, str)) {
242217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
243217SN/A    }
244217SN/A
245217SN/A    // code below stolen from VectorParam<T>::parse().
246217SN/A    // it would be nice to unify these somehow...
247217SN/A
248217SN/A    vector<string> tokens;
249217SN/A
250217SN/A    tokenize(tokens, str, ' ');
251217SN/A
252217SN/A    // Need this if we were doing a vector
253217SN/A    // value.resize(tokens.size());
254217SN/A
255217SN/A    if (tokens.size() != size) {
256217SN/A        fatal("Array size mismatch on %s:%s'\n", section, name);
257217SN/A    }
258217SN/A
2596227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
260217SN/A        // need to parse into local variable to handle vector<bool>,
261217SN/A        // for which operator[] returns a special reference class
262217SN/A        // that's not the same as 'bool&', (since it's a packed
263217SN/A        // vector)
264217SN/A        T scalar_value;
265217SN/A        if (!parseParam(tokens[i], scalar_value)) {
266217SN/A            string err("could not parse \"");
267217SN/A
268217SN/A            err += str;
269217SN/A            err += "\"";
270217SN/A
271217SN/A            fatal(err);
272217SN/A        }
273217SN/A
274217SN/A        // assign parsed value to vector
275217SN/A        param[i] = scalar_value;
276217SN/A    }
277217SN/A}
278217SN/A
2794841Ssaidi@eecs.umich.edutemplate <class T>
2804841Ssaidi@eecs.umich.eduvoid
2816225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string &section,
2826225Snate@binkert.org             const string &name, vector<T> &param)
2834841Ssaidi@eecs.umich.edu{
2846225Snate@binkert.org    string str;
2854841Ssaidi@eecs.umich.edu    if (!cp->find(section, name, str)) {
2864841Ssaidi@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
2874841Ssaidi@eecs.umich.edu    }
2884841Ssaidi@eecs.umich.edu
2894841Ssaidi@eecs.umich.edu    // code below stolen from VectorParam<T>::parse().
2904841Ssaidi@eecs.umich.edu    // it would be nice to unify these somehow...
2914841Ssaidi@eecs.umich.edu
2924841Ssaidi@eecs.umich.edu    vector<string> tokens;
2934841Ssaidi@eecs.umich.edu
2944841Ssaidi@eecs.umich.edu    tokenize(tokens, str, ' ');
2954841Ssaidi@eecs.umich.edu
2964841Ssaidi@eecs.umich.edu    // Need this if we were doing a vector
2974841Ssaidi@eecs.umich.edu    // value.resize(tokens.size());
2984841Ssaidi@eecs.umich.edu
2994841Ssaidi@eecs.umich.edu    param.resize(tokens.size());
3004841Ssaidi@eecs.umich.edu
3016227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
3024841Ssaidi@eecs.umich.edu        // need to parse into local variable to handle vector<bool>,
3034841Ssaidi@eecs.umich.edu        // for which operator[] returns a special reference class
3044841Ssaidi@eecs.umich.edu        // that's not the same as 'bool&', (since it's a packed
3054841Ssaidi@eecs.umich.edu        // vector)
3064841Ssaidi@eecs.umich.edu        T scalar_value;
3074841Ssaidi@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
3084841Ssaidi@eecs.umich.edu            string err("could not parse \"");
3094841Ssaidi@eecs.umich.edu
3104841Ssaidi@eecs.umich.edu            err += str;
3114841Ssaidi@eecs.umich.edu            err += "\"";
3124841Ssaidi@eecs.umich.edu
3134841Ssaidi@eecs.umich.edu            fatal(err);
3144841Ssaidi@eecs.umich.edu        }
3154841Ssaidi@eecs.umich.edu
3164841Ssaidi@eecs.umich.edu        // assign parsed value to vector
3174841Ssaidi@eecs.umich.edu        param[i] = scalar_value;
3184841Ssaidi@eecs.umich.edu    }
3194841Ssaidi@eecs.umich.edu}
3204841Ssaidi@eecs.umich.edu
321237SN/Avoid
3226225Snate@binkert.orgobjParamIn(Checkpoint *cp, const string &section,
3236225Snate@binkert.org           const string &name, SimObject * &param)
324237SN/A{
325237SN/A    if (!cp->findObj(section, name, param)) {
326237SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
327237SN/A    }
328237SN/A}
329237SN/A
330237SN/A
3315543Ssaidi@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type)                               \
3325543Ssaidi@eecs.umich.edutemplate void                                                           \
3336225Snate@binkert.orgparamOut(ostream &os, const string &name, type const &param);           \
3345543Ssaidi@eecs.umich.edutemplate void                                                           \
3356225Snate@binkert.orgparamIn(Checkpoint *cp, const string &section,                          \
3366225Snate@binkert.org        const string &name, type & param);                              \
3376820SLisa.Hsu@amd.comtemplate bool                                                           \
3386820SLisa.Hsu@amd.comoptParamIn(Checkpoint *cp, const string &section,                       \
3396820SLisa.Hsu@amd.com        const string &name, type & param);                              \
3405543Ssaidi@eecs.umich.edutemplate void                                                           \
3416225Snate@binkert.orgarrayParamOut(ostream &os, const string &name,                          \
3426227Snate@binkert.org              type const *param, unsigned size);                        \
3435543Ssaidi@eecs.umich.edutemplate void                                                           \
3446225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string &section,                     \
3456227Snate@binkert.org             const string &name, type *param, unsigned size);           \
3465543Ssaidi@eecs.umich.edutemplate void                                                           \
3476225Snate@binkert.orgarrayParamOut(ostream &os, const string &name,                          \
3486225Snate@binkert.org              const vector<type> &param);                               \
3495543Ssaidi@eecs.umich.edutemplate void                                                           \
3506225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string &section,                     \
3516225Snate@binkert.org             const string &name, vector<type> &param);
352217SN/A
3531642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char)
3541642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char)
3551642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short)
3561642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short)
3571642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int)
3581642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int)
3591642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long)
3601642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long)
3611642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long)
3621642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long)
363219SN/AINSTANTIATE_PARAM_TEMPLATES(bool)
3645992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(float)
3655992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(double)
366217SN/AINSTANTIATE_PARAM_TEMPLATES(string)
367217SN/A
368217SN/A
369395SN/A/////////////////////////////
370395SN/A
371395SN/A/// Container for serializing global variables (not associated with
372395SN/A/// any serialized object).
373395SN/Aclass Globals : public Serializable
3742SN/A{
375395SN/A  public:
376512SN/A    const string name() const;
377510SN/A    void serialize(ostream &os);
378395SN/A    void unserialize(Checkpoint *cp);
379395SN/A};
3802SN/A
381395SN/A/// The one and only instance of the Globals class.
382395SN/AGlobals globals;
3832SN/A
384512SN/Aconst string
385395SN/AGlobals::name() const
3862SN/A{
387395SN/A    return "Globals";
3882SN/A}
3892SN/A
3902SN/Avoid
391510SN/AGlobals::serialize(ostream &os)
3922SN/A{
393395SN/A    nameOut(os);
394395SN/A    SERIALIZE_SCALAR(curTick);
395395SN/A
396395SN/A    nameOut(os, "MainEventQueue");
397395SN/A    mainEventQueue.serialize(os);
3982SN/A}
3992SN/A
4002SN/Avoid
401395SN/AGlobals::unserialize(Checkpoint *cp)
4022SN/A{
403395SN/A    const string &section = name();
404395SN/A    UNSERIALIZE_SCALAR(curTick);
4052SN/A
406395SN/A    mainEventQueue.unserialize(cp, "MainEventQueue");
4072SN/A}
4082SN/A
4095739Snate@binkert.orgSerializable::Serializable()
4105739Snate@binkert.org{
4115739Snate@binkert.org}
4125739Snate@binkert.org
4135739Snate@binkert.orgSerializable::~Serializable()
4145739Snate@binkert.org{
4155739Snate@binkert.org}
4165739Snate@binkert.org
4175739Snate@binkert.orgvoid
4186225Snate@binkert.orgSerializable::serialize(ostream &os)
4195739Snate@binkert.org{
4205739Snate@binkert.org}
4215739Snate@binkert.org
4225739Snate@binkert.orgvoid
4236225Snate@binkert.orgSerializable::unserialize(Checkpoint *cp, const string &section)
4245739Snate@binkert.org{
4255739Snate@binkert.org}
4265739Snate@binkert.org
4272SN/Avoid
4286225Snate@binkert.orgSerializable::serializeAll(const string &cpt_dir)
4292SN/A{
4307491Ssteve.reinhardt@amd.com    string dir = Checkpoint::setDir(cpt_dir);
431363SN/A    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
432449SN/A            fatal("couldn't mkdir %s\n", dir);
433363SN/A
434449SN/A    string cpt_file = dir + Checkpoint::baseFilename;
435395SN/A    ofstream outstream(cpt_file.c_str());
4362SN/A    time_t t = time(NULL);
4375581Ssaidi@eecs.umich.edu    if (!outstream.is_open())
4385581Ssaidi@eecs.umich.edu        fatal("Unable to open file %s for writing\n", cpt_file.c_str());
4396818SLisa.Hsu@amd.com    outstream << "## checkpoint generated: " << ctime(&t);
4402SN/A
441395SN/A    globals.serialize(outstream);
442395SN/A    SimObject::serializeAll(outstream);
443395SN/A}
4442SN/A
4452797Sktlim@umich.eduvoid
4466225Snate@binkert.orgSerializable::unserializeAll(const string &cpt_dir)
4472797Sktlim@umich.edu{
4487491Ssteve.reinhardt@amd.com    string dir = Checkpoint::setDir(cpt_dir);
4492797Sktlim@umich.edu
4507491Ssteve.reinhardt@amd.com    DPRINTFR(Config, "Loading checkpoint dir '%s'\n", dir);
4517491Ssteve.reinhardt@amd.com    Checkpoint *cp = new Checkpoint(dir);
4522797Sktlim@umich.edu    unserializeGlobals(cp);
4532797Sktlim@umich.edu    SimObject::unserializeAll(cp);
4542797Sktlim@umich.edu}
4552SN/A
456395SN/Avoid
457395SN/ASerializable::unserializeGlobals(Checkpoint *cp)
458395SN/A{
459395SN/A    globals.unserialize(cp);
460395SN/A}
4612SN/A
4622SN/Avoid
4636225Snate@binkert.orgdebug_serialize(const string &cpt_dir)
4642SN/A{
4652868Sktlim@umich.edu    Serializable::serializeAll(cpt_dir);
4662SN/A}
4672SN/A
4682SN/A
4692SN/A////////////////////////////////////////////////////////////////////////
4702SN/A//
471395SN/A// SerializableClass member definitions
4722SN/A//
4732SN/A////////////////////////////////////////////////////////////////////////
4742SN/A
475395SN/A// Map of class names to SerializableBuilder creation functions.
4762SN/A// Need to make this a pointer so we can force initialization on the
477395SN/A// first reference; otherwise, some SerializableClass constructors
4782SN/A// may be invoked before the classMap constructor.
4796225Snate@binkert.orgmap<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0;
4802SN/A
481395SN/A// SerializableClass constructor: add mapping to classMap
482395SN/ASerializableClass::SerializableClass(const string &className,
4836225Snate@binkert.org                                     CreateFunc createFunc)
4842SN/A{
4852SN/A    if (classMap == NULL)
4866225Snate@binkert.org        classMap = new map<string, SerializableClass::CreateFunc>();
4872SN/A
4882SN/A    if ((*classMap)[className])
4896225Snate@binkert.org        fatal("Error: simulation object class %s redefined\n", className);
4902SN/A
4912SN/A    // add className --> createFunc to class map
4922SN/A    (*classMap)[className] = createFunc;
4932SN/A}
4942SN/A
4952SN/A//
4962SN/A//
497395SN/ASerializable *
4986225Snate@binkert.orgSerializableClass::createObject(Checkpoint *cp, const string &section)
4992SN/A{
500237SN/A    string className;
5012SN/A
502237SN/A    if (!cp->find(section, "type", className)) {
503395SN/A        fatal("Serializable::create: no 'type' entry in section '%s'.\n",
504237SN/A              section);
5052SN/A    }
5062SN/A
507237SN/A    CreateFunc createFunc = (*classMap)[className];
508237SN/A
509237SN/A    if (createFunc == NULL) {
510395SN/A        fatal("Serializable::create: no create function for class '%s'.\n",
511237SN/A              className);
5122SN/A    }
5132SN/A
514395SN/A    Serializable *object = createFunc(cp, section);
5152SN/A
5162SN/A    assert(object != NULL);
5172SN/A
5182SN/A    return object;
5192SN/A}
5202SN/A
521237SN/A
522395SN/ASerializable *
5236225Snate@binkert.orgSerializable::create(Checkpoint *cp, const string &section)
524237SN/A{
525395SN/A    Serializable *object = SerializableClass::createObject(cp, section);
526237SN/A    object->unserialize(cp, section);
527237SN/A    return object;
528237SN/A}
529237SN/A
530237SN/A
5317491Ssteve.reinhardt@amd.comconst char *Checkpoint::baseFilename = "m5.cpt";
5327491Ssteve.reinhardt@amd.com
5337491Ssteve.reinhardt@amd.comstring Checkpoint::currentDirectory;
5347491Ssteve.reinhardt@amd.com
5357491Ssteve.reinhardt@amd.comstring
5367491Ssteve.reinhardt@amd.comCheckpoint::setDir(const string &name)
5377491Ssteve.reinhardt@amd.com{
5387491Ssteve.reinhardt@amd.com    // use csprintf to insert curTick into directory name if it
5397491Ssteve.reinhardt@amd.com    // appears to have a format placeholder in it.
5407491Ssteve.reinhardt@amd.com    currentDirectory = (name.find("%") != string::npos) ?
5417491Ssteve.reinhardt@amd.com        csprintf(name, curTick) : name;
5427491Ssteve.reinhardt@amd.com    if (currentDirectory[currentDirectory.size() - 1] != '/')
5437491Ssteve.reinhardt@amd.com        currentDirectory += "/";
5447491Ssteve.reinhardt@amd.com    return currentDirectory;
5457491Ssteve.reinhardt@amd.com}
5467491Ssteve.reinhardt@amd.com
5477491Ssteve.reinhardt@amd.comstring
5487491Ssteve.reinhardt@amd.comCheckpoint::dir()
5497491Ssteve.reinhardt@amd.com{
5507491Ssteve.reinhardt@amd.com    return currentDirectory;
5517491Ssteve.reinhardt@amd.com}
5527491Ssteve.reinhardt@amd.com
5537491Ssteve.reinhardt@amd.com
5547491Ssteve.reinhardt@amd.comCheckpoint::Checkpoint(const string &cpt_dir)
5557491Ssteve.reinhardt@amd.com    : db(new IniFile), cptDir(cpt_dir)
556237SN/A{
557449SN/A    string filename = cpt_dir + "/" + Checkpoint::baseFilename;
558237SN/A    if (!db->load(filename)) {
559237SN/A        fatal("Can't load checkpoint file '%s'\n", filename);
560237SN/A    }
561237SN/A}
562237SN/A
563237SN/A
564237SN/Abool
5656225Snate@binkert.orgCheckpoint::find(const string &section, const string &entry, string &value)
566237SN/A{
567237SN/A    return db->find(section, entry, value);
568237SN/A}
569237SN/A
570237SN/A
571237SN/Abool
5726225Snate@binkert.orgCheckpoint::findObj(const string &section, const string &entry,
5734000Ssaidi@eecs.umich.edu                    SimObject *&value)
574237SN/A{
575237SN/A    string path;
576237SN/A
577237SN/A    if (!db->find(section, entry, path))
578237SN/A        return false;
579237SN/A
5804000Ssaidi@eecs.umich.edu    value = resolveSimObject(path);
5814000Ssaidi@eecs.umich.edu    return true;
582237SN/A}
583304SN/A
584304SN/A
585304SN/Abool
5866225Snate@binkert.orgCheckpoint::sectionExists(const string &section)
587304SN/A{
588304SN/A    return db->sectionExists(section);
589304SN/A}
590