serialize.cc revision 10905
12SN/A/*
210905Sandreas.sandberg@arm.com * Copyright (c) 2015 ARM Limited
310905Sandreas.sandberg@arm.com * All rights reserved
410905Sandreas.sandberg@arm.com *
510905Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
610905Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
710905Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
810905Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
910905Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1010905Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1110905Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1210905Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1310905Sandreas.sandberg@arm.com *
141762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
159983Sstever@gmail.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
169983Sstever@gmail.com * Copyright (c) 2013 Mark D. Hill and David A. Wood
172SN/A * All rights reserved.
182SN/A *
192SN/A * Redistribution and use in source and binary forms, with or without
202SN/A * modification, are permitted provided that the following conditions are
212SN/A * met: redistributions of source code must retain the above copyright
222SN/A * notice, this list of conditions and the following disclaimer;
232SN/A * redistributions in binary form must reproduce the above copyright
242SN/A * notice, this list of conditions and the following disclaimer in the
252SN/A * documentation and/or other materials provided with the distribution;
262SN/A * neither the name of the copyright holders nor the names of its
272SN/A * contributors may be used to endorse or promote products derived from
282SN/A * this software without specific prior written permission.
292SN/A *
302SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
312SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
322SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
332SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
342SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
352SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
362SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
372SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
382SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
392SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
402SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
412665Ssaidi@eecs.umich.edu *
422760Sbinkertn@umich.edu * Authors: Nathan Binkert
432760Sbinkertn@umich.edu *          Erik Hallnor
442665Ssaidi@eecs.umich.edu *          Steve Reinhardt
4510905Sandreas.sandberg@arm.com *          Andreas Sandberg
462SN/A */
472SN/A
488229Snate@binkert.org#include <sys/stat.h>
492SN/A#include <sys/time.h>
50363SN/A#include <sys/types.h>
512SN/A
528229Snate@binkert.org#include <cerrno>
532SN/A#include <fstream>
542SN/A#include <list>
552SN/A#include <string>
562SN/A#include <vector>
572SN/A
58363SN/A#include "base/inifile.hh"
5956SN/A#include "base/misc.hh"
601388SN/A#include "base/output.hh"
61217SN/A#include "base/str.hh"
62363SN/A#include "base/trace.hh"
6310905Sandreas.sandberg@arm.com#include "debug/Checkpoint.hh"
6456SN/A#include "sim/eventq.hh"
6556SN/A#include "sim/serialize.hh"
6656SN/A#include "sim/sim_events.hh"
671638SN/A#include "sim/sim_exit.hh"
6856SN/A#include "sim/sim_object.hh"
692SN/A
702356SN/A// For stat reset hack
712356SN/A#include "sim/stat_control.hh"
722356SN/A
732SN/Ausing namespace std;
742SN/A
754762Snate@binkert.org//
764762Snate@binkert.org// The base implementations use to_number for parsing and '<<' for
774762Snate@binkert.org// displaying, suitable for integer types.
784762Snate@binkert.org//
794762Snate@binkert.orgtemplate <class T>
804762Snate@binkert.orgbool
814762Snate@binkert.orgparseParam(const string &s, T &value)
824762Snate@binkert.org{
834762Snate@binkert.org    return to_number(s, value);
844762Snate@binkert.org}
854762Snate@binkert.org
864762Snate@binkert.orgtemplate <class T>
874762Snate@binkert.orgvoid
8810905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const T &value)
894762Snate@binkert.org{
904762Snate@binkert.org    os << value;
914762Snate@binkert.org}
924762Snate@binkert.org
934762Snate@binkert.org//
944762Snate@binkert.org// Template specializations:
954762Snate@binkert.org// - char (8-bit integer)
964762Snate@binkert.org// - floating-point types
974762Snate@binkert.org// - bool
984762Snate@binkert.org// - string
994762Snate@binkert.org//
1004762Snate@binkert.org
1014762Snate@binkert.org// Treat 8-bit ints (chars) as ints on output, not as chars
1024762Snate@binkert.orgtemplate <>
1034762Snate@binkert.orgvoid
10410905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const char &value)
1057494Ssteve.reinhardt@amd.com{
1067494Ssteve.reinhardt@amd.com    os << (int)value;
1077494Ssteve.reinhardt@amd.com}
1087494Ssteve.reinhardt@amd.com
1097494Ssteve.reinhardt@amd.com
1107494Ssteve.reinhardt@amd.comtemplate <>
1117494Ssteve.reinhardt@amd.comvoid
11210905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const signed char &value)
1134762Snate@binkert.org{
1144762Snate@binkert.org    os << (int)value;
1154762Snate@binkert.org}
1164762Snate@binkert.org
1174762Snate@binkert.org
1184762Snate@binkert.orgtemplate <>
1194762Snate@binkert.orgvoid
12010905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const unsigned char &value)
1214762Snate@binkert.org{
1224762Snate@binkert.org    os << (unsigned int)value;
1234762Snate@binkert.org}
1244762Snate@binkert.org
1254762Snate@binkert.org
1264762Snate@binkert.orgtemplate <>
1274762Snate@binkert.orgbool
1284762Snate@binkert.orgparseParam(const string &s, float &value)
1294762Snate@binkert.org{
13010386Sandreas.hansson@arm.com    return to_number(s, value);
1314762Snate@binkert.org}
1324762Snate@binkert.org
1334762Snate@binkert.orgtemplate <>
1344762Snate@binkert.orgbool
1354762Snate@binkert.orgparseParam(const string &s, double &value)
1364762Snate@binkert.org{
13710386Sandreas.hansson@arm.com    return to_number(s, value);
1384762Snate@binkert.org}
1394762Snate@binkert.org
1404762Snate@binkert.orgtemplate <>
1414762Snate@binkert.orgbool
1424762Snate@binkert.orgparseParam(const string &s, bool &value)
1434762Snate@binkert.org{
14410386Sandreas.hansson@arm.com    return to_bool(s, value);
1454762Snate@binkert.org}
1464762Snate@binkert.org
1474762Snate@binkert.org// Display bools as strings
1484762Snate@binkert.orgtemplate <>
1494762Snate@binkert.orgvoid
15010905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const bool &value)
1514762Snate@binkert.org{
1524762Snate@binkert.org    os << (value ? "true" : "false");
1534762Snate@binkert.org}
1544762Snate@binkert.org
1554762Snate@binkert.org
1564762Snate@binkert.org// String requires no processing to speak of
1574762Snate@binkert.orgtemplate <>
1584762Snate@binkert.orgbool
1594762Snate@binkert.orgparseParam(const string &s, string &value)
1604762Snate@binkert.org{
1614762Snate@binkert.org    value = s;
1624762Snate@binkert.org    return true;
1634762Snate@binkert.org}
1644762Snate@binkert.org
1652287SN/Aint Serializable::ckptMaxCount = 0;
1662287SN/Aint Serializable::ckptCount = 0;
1672287SN/Aint Serializable::ckptPrevCount = -1;
16810905Sandreas.sandberg@arm.comstd::stack<std::string> Serializable::path;
1692SN/A
170217SN/Atemplate <class T>
1712SN/Avoid
17210905Sandreas.sandberg@arm.comparamOut(CheckpointOut &os, const string &name, const T &param)
1732SN/A{
174217SN/A    os << name << "=";
175217SN/A    showParam(os, param);
176217SN/A    os << "\n";
1772SN/A}
1782SN/A
1794841Ssaidi@eecs.umich.edutemplate <class T>
1804841Ssaidi@eecs.umich.eduvoid
18110905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name, const vector<T> &param)
1824841Ssaidi@eecs.umich.edu{
1836227Snate@binkert.org    typename vector<T>::size_type size = param.size();
1844841Ssaidi@eecs.umich.edu    os << name << "=";
1854841Ssaidi@eecs.umich.edu    if (size > 0)
1864841Ssaidi@eecs.umich.edu        showParam(os, param[0]);
1876227Snate@binkert.org    for (typename vector<T>::size_type i = 1; i < size; ++i) {
1884841Ssaidi@eecs.umich.edu        os << " ";
1894841Ssaidi@eecs.umich.edu        showParam(os, param[i]);
1904841Ssaidi@eecs.umich.edu    }
1914841Ssaidi@eecs.umich.edu    os << "\n";
1924841Ssaidi@eecs.umich.edu}
1934841Ssaidi@eecs.umich.edu
1947948SAli.Saidi@ARM.comtemplate <class T>
1957948SAli.Saidi@ARM.comvoid
19610905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name, const list<T> &param)
1977948SAli.Saidi@ARM.com{
1987948SAli.Saidi@ARM.com    typename list<T>::const_iterator it = param.begin();
1997948SAli.Saidi@ARM.com
2007948SAli.Saidi@ARM.com    os << name << "=";
2017948SAli.Saidi@ARM.com    if (param.size() > 0)
2027948SAli.Saidi@ARM.com        showParam(os, *it);
2037948SAli.Saidi@ARM.com    it++;
2047948SAli.Saidi@ARM.com    while (it != param.end()) {
2057948SAli.Saidi@ARM.com        os << " ";
2067948SAli.Saidi@ARM.com        showParam(os, *it);
2077948SAli.Saidi@ARM.com        it++;
2087948SAli.Saidi@ARM.com    }
2097948SAli.Saidi@ARM.com    os << "\n";
2107948SAli.Saidi@ARM.com}
211217SN/A
212217SN/Atemplate <class T>
213217SN/Avoid
21410905Sandreas.sandberg@arm.comparamIn(CheckpointIn &cp, const string &name, T &param)
2152SN/A{
21610905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
2176225Snate@binkert.org    string str;
21810905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
219217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
220217SN/A    }
2212SN/A}
2222SN/A
2236820SLisa.Hsu@amd.comtemplate <class T>
2246820SLisa.Hsu@amd.combool
22510905Sandreas.sandberg@arm.comoptParamIn(CheckpointIn &cp, const string &name, T &param)
2266820SLisa.Hsu@amd.com{
22710905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
2286820SLisa.Hsu@amd.com    string str;
22910905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
2306820SLisa.Hsu@amd.com        warn("optional parameter %s:%s not present\n", section, name);
2316820SLisa.Hsu@amd.com        return false;
2326820SLisa.Hsu@amd.com    } else {
2336820SLisa.Hsu@amd.com        return true;
2346820SLisa.Hsu@amd.com    }
2356820SLisa.Hsu@amd.com}
236217SN/A
237217SN/Atemplate <class T>
238217SN/Avoid
23910905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name,
24010905Sandreas.sandberg@arm.com              const T *param, unsigned size)
241217SN/A{
242217SN/A    os << name << "=";
243217SN/A    if (size > 0)
244217SN/A        showParam(os, param[0]);
2456227Snate@binkert.org    for (unsigned i = 1; i < size; ++i) {
246217SN/A        os << " ";
247217SN/A        showParam(os, param[i]);
248217SN/A    }
249217SN/A    os << "\n";
250217SN/A}
251217SN/A
252217SN/A
253217SN/Atemplate <class T>
254217SN/Avoid
25510905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
256217SN/A{
25710905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
2586225Snate@binkert.org    string str;
25910905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
260217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
261217SN/A    }
262217SN/A
263217SN/A    // code below stolen from VectorParam<T>::parse().
264217SN/A    // it would be nice to unify these somehow...
265217SN/A
266217SN/A    vector<string> tokens;
267217SN/A
268217SN/A    tokenize(tokens, str, ' ');
269217SN/A
270217SN/A    // Need this if we were doing a vector
271217SN/A    // value.resize(tokens.size());
272217SN/A
273217SN/A    if (tokens.size() != size) {
274217SN/A        fatal("Array size mismatch on %s:%s'\n", section, name);
275217SN/A    }
276217SN/A
2776227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
278217SN/A        // need to parse into local variable to handle vector<bool>,
279217SN/A        // for which operator[] returns a special reference class
280217SN/A        // that's not the same as 'bool&', (since it's a packed
281217SN/A        // vector)
28210905Sandreas.sandberg@arm.com        T scalar_value;
283217SN/A        if (!parseParam(tokens[i], scalar_value)) {
284217SN/A            string err("could not parse \"");
285217SN/A
286217SN/A            err += str;
287217SN/A            err += "\"";
288217SN/A
289217SN/A            fatal(err);
290217SN/A        }
291217SN/A
292217SN/A        // assign parsed value to vector
293217SN/A        param[i] = scalar_value;
294217SN/A    }
295217SN/A}
296217SN/A
2974841Ssaidi@eecs.umich.edutemplate <class T>
2984841Ssaidi@eecs.umich.eduvoid
29910905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
3004841Ssaidi@eecs.umich.edu{
30110905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
3026225Snate@binkert.org    string str;
30310905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
3044841Ssaidi@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
3054841Ssaidi@eecs.umich.edu    }
3064841Ssaidi@eecs.umich.edu
3074841Ssaidi@eecs.umich.edu    // code below stolen from VectorParam<T>::parse().
3084841Ssaidi@eecs.umich.edu    // it would be nice to unify these somehow...
3094841Ssaidi@eecs.umich.edu
3104841Ssaidi@eecs.umich.edu    vector<string> tokens;
3114841Ssaidi@eecs.umich.edu
3124841Ssaidi@eecs.umich.edu    tokenize(tokens, str, ' ');
3134841Ssaidi@eecs.umich.edu
3144841Ssaidi@eecs.umich.edu    // Need this if we were doing a vector
3154841Ssaidi@eecs.umich.edu    // value.resize(tokens.size());
3164841Ssaidi@eecs.umich.edu
3174841Ssaidi@eecs.umich.edu    param.resize(tokens.size());
3184841Ssaidi@eecs.umich.edu
3196227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
3204841Ssaidi@eecs.umich.edu        // need to parse into local variable to handle vector<bool>,
3214841Ssaidi@eecs.umich.edu        // for which operator[] returns a special reference class
3224841Ssaidi@eecs.umich.edu        // that's not the same as 'bool&', (since it's a packed
3234841Ssaidi@eecs.umich.edu        // vector)
32410905Sandreas.sandberg@arm.com        T scalar_value;
3254841Ssaidi@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
3264841Ssaidi@eecs.umich.edu            string err("could not parse \"");
3274841Ssaidi@eecs.umich.edu
3284841Ssaidi@eecs.umich.edu            err += str;
3294841Ssaidi@eecs.umich.edu            err += "\"";
3304841Ssaidi@eecs.umich.edu
3314841Ssaidi@eecs.umich.edu            fatal(err);
3324841Ssaidi@eecs.umich.edu        }
3334841Ssaidi@eecs.umich.edu
3344841Ssaidi@eecs.umich.edu        // assign parsed value to vector
3354841Ssaidi@eecs.umich.edu        param[i] = scalar_value;
3364841Ssaidi@eecs.umich.edu    }
3374841Ssaidi@eecs.umich.edu}
3384841Ssaidi@eecs.umich.edu
3397948SAli.Saidi@ARM.comtemplate <class T>
3407948SAli.Saidi@ARM.comvoid
34110905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
3427948SAli.Saidi@ARM.com{
34310905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
3447948SAli.Saidi@ARM.com    string str;
34510905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
3467948SAli.Saidi@ARM.com        fatal("Can't unserialize '%s:%s'\n", section, name);
3477948SAli.Saidi@ARM.com    }
3487948SAli.Saidi@ARM.com    param.clear();
3497948SAli.Saidi@ARM.com
3507948SAli.Saidi@ARM.com    vector<string> tokens;
3517948SAli.Saidi@ARM.com    tokenize(tokens, str, ' ');
3527948SAli.Saidi@ARM.com
3537948SAli.Saidi@ARM.com    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
35410905Sandreas.sandberg@arm.com        T scalar_value;
3557948SAli.Saidi@ARM.com        if (!parseParam(tokens[i], scalar_value)) {
3567948SAli.Saidi@ARM.com            string err("could not parse \"");
3577948SAli.Saidi@ARM.com
3587948SAli.Saidi@ARM.com            err += str;
3597948SAli.Saidi@ARM.com            err += "\"";
3607948SAli.Saidi@ARM.com
3617948SAli.Saidi@ARM.com            fatal(err);
3627948SAli.Saidi@ARM.com        }
3637948SAli.Saidi@ARM.com
3647948SAli.Saidi@ARM.com        // assign parsed value to vector
3657948SAli.Saidi@ARM.com        param.push_back(scalar_value);
3667948SAli.Saidi@ARM.com    }
3677948SAli.Saidi@ARM.com}
3687948SAli.Saidi@ARM.com
3697948SAli.Saidi@ARM.com
370237SN/Avoid
37110905Sandreas.sandberg@arm.comobjParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
372237SN/A{
37310905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
37410905Sandreas.sandberg@arm.com    if (!cp.findObj(section, name, param)) {
375237SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
376237SN/A    }
377237SN/A}
378237SN/A
379237SN/A
3805543Ssaidi@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type)                               \
38110905Sandreas.sandberg@arm.com    template void                                                       \
38210905Sandreas.sandberg@arm.com    paramOut(CheckpointOut &os, const string &name, type const &param); \
38310905Sandreas.sandberg@arm.com    template void                                                       \
38410905Sandreas.sandberg@arm.com    paramIn(CheckpointIn &cp, const string &name, type & param);        \
38510905Sandreas.sandberg@arm.com    template bool                                                       \
38610905Sandreas.sandberg@arm.com    optParamIn(CheckpointIn &cp, const string &name, type & param);     \
38710905Sandreas.sandberg@arm.com    template void                                                       \
38810905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
38910905Sandreas.sandberg@arm.com                  type const *param, unsigned size);                    \
39010905Sandreas.sandberg@arm.com    template void                                                       \
39110905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
39210905Sandreas.sandberg@arm.com                 type *param, unsigned size);                           \
39310905Sandreas.sandberg@arm.com    template void                                                       \
39410905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
39510905Sandreas.sandberg@arm.com                  const vector<type> &param);                           \
39610905Sandreas.sandberg@arm.com    template void                                                       \
39710905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
39810905Sandreas.sandberg@arm.com                 vector<type> &param);                                  \
39910905Sandreas.sandberg@arm.com    template void                                                       \
40010905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
40110905Sandreas.sandberg@arm.com                  const list<type> &param);                             \
40210905Sandreas.sandberg@arm.com    template void                                                       \
40310905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
40410905Sandreas.sandberg@arm.com                 list<type> &param);
405217SN/A
4067494Ssteve.reinhardt@amd.comINSTANTIATE_PARAM_TEMPLATES(char)
4071642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char)
4081642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char)
4091642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short)
4101642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short)
4111642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int)
4121642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int)
4131642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long)
4141642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long)
4151642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long)
4161642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long)
417219SN/AINSTANTIATE_PARAM_TEMPLATES(bool)
4185992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(float)
4195992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(double)
420217SN/AINSTANTIATE_PARAM_TEMPLATES(string)
421217SN/A
422217SN/A
423395SN/A/////////////////////////////
424395SN/A
425395SN/A/// Container for serializing global variables (not associated with
426395SN/A/// any serialized object).
427395SN/Aclass Globals : public Serializable
4282SN/A{
429395SN/A  public:
43010905Sandreas.sandberg@arm.com    Globals()
43110905Sandreas.sandberg@arm.com        : unserializedCurTick(0) {}
43210905Sandreas.sandberg@arm.com
43310905Sandreas.sandberg@arm.com    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
43410905Sandreas.sandberg@arm.com    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
43510905Sandreas.sandberg@arm.com
43610905Sandreas.sandberg@arm.com    Tick unserializedCurTick;
437395SN/A};
4382SN/A
439395SN/A/// The one and only instance of the Globals class.
440395SN/AGlobals globals;
4412SN/A
44210905Sandreas.sandberg@arm.comvoid
44310905Sandreas.sandberg@arm.comGlobals::serialize(CheckpointOut &cp) const
4442SN/A{
44510905Sandreas.sandberg@arm.com    paramOut(cp, "curTick", curTick());
44610905Sandreas.sandberg@arm.com    paramOut(cp, "numMainEventQueues", numMainEventQueues);
44710905Sandreas.sandberg@arm.com
4482SN/A}
4492SN/A
4502SN/Avoid
45110905Sandreas.sandberg@arm.comGlobals::unserialize(CheckpointIn &cp)
4522SN/A{
45310905Sandreas.sandberg@arm.com    paramIn(cp, "curTick", unserializedCurTick);
45410905Sandreas.sandberg@arm.com    paramIn(cp, "numMainEventQueues", numMainEventQueues);
4552SN/A}
4562SN/A
4575739Snate@binkert.orgSerializable::Serializable()
4585739Snate@binkert.org{
4595739Snate@binkert.org}
4605739Snate@binkert.org
4615739Snate@binkert.orgSerializable::~Serializable()
4625739Snate@binkert.org{
4635739Snate@binkert.org}
4645739Snate@binkert.org
4655739Snate@binkert.orgvoid
46610905Sandreas.sandberg@arm.comSerializable::serializeSection(CheckpointOut &cp, const char *name) const
4675739Snate@binkert.org{
46810905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
46910905Sandreas.sandberg@arm.com    serialize(cp);
4705739Snate@binkert.org}
4715739Snate@binkert.org
4725739Snate@binkert.orgvoid
47310905Sandreas.sandberg@arm.comSerializable::serializeSectionOld(CheckpointOut &cp, const char *name)
4745739Snate@binkert.org{
47510905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
47610905Sandreas.sandberg@arm.com    serializeOld(cp);
47710905Sandreas.sandberg@arm.com}
47810905Sandreas.sandberg@arm.com
47910905Sandreas.sandberg@arm.comvoid
48010905Sandreas.sandberg@arm.comSerializable::unserializeSection(CheckpointIn &cp, const char *name)
48110905Sandreas.sandberg@arm.com{
48210905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
48310905Sandreas.sandberg@arm.com    unserialize(cp);
4845739Snate@binkert.org}
4855739Snate@binkert.org
4862SN/Avoid
4876225Snate@binkert.orgSerializable::serializeAll(const string &cpt_dir)
4882SN/A{
48910905Sandreas.sandberg@arm.com    string dir = CheckpointIn::setDir(cpt_dir);
490363SN/A    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
491449SN/A            fatal("couldn't mkdir %s\n", dir);
492363SN/A
49310905Sandreas.sandberg@arm.com    string cpt_file = dir + CheckpointIn::baseFilename;
494395SN/A    ofstream outstream(cpt_file.c_str());
4952SN/A    time_t t = time(NULL);
4965581Ssaidi@eecs.umich.edu    if (!outstream.is_open())
4975581Ssaidi@eecs.umich.edu        fatal("Unable to open file %s for writing\n", cpt_file.c_str());
4986818SLisa.Hsu@amd.com    outstream << "## checkpoint generated: " << ctime(&t);
4992SN/A
50010905Sandreas.sandberg@arm.com    globals.serializeSection(outstream, "Globals");
50110905Sandreas.sandberg@arm.com    for (uint32_t i = 0; i < numMainEventQueues; ++i)
50210905Sandreas.sandberg@arm.com        mainEventQueue[i]->serializeSection(outstream, "MainEventQueue");
50310905Sandreas.sandberg@arm.com
504395SN/A    SimObject::serializeAll(outstream);
505395SN/A}
5062SN/A
5072797Sktlim@umich.eduvoid
50810905Sandreas.sandberg@arm.comSerializable::unserializeGlobals(CheckpointIn &cp)
509395SN/A{
51010905Sandreas.sandberg@arm.com    globals.unserializeSection(cp, "Globals");
51110905Sandreas.sandberg@arm.com
51210905Sandreas.sandberg@arm.com    for (uint32_t i = 0; i < numMainEventQueues; ++i) {
51310905Sandreas.sandberg@arm.com        mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
51410905Sandreas.sandberg@arm.com        mainEventQueue[i]->unserializeSection(cp, "MainEventQueue");
51510905Sandreas.sandberg@arm.com    }
51610905Sandreas.sandberg@arm.com}
51710905Sandreas.sandberg@arm.com
51810905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::~ScopedCheckpointSection()
51910905Sandreas.sandberg@arm.com{
52010905Sandreas.sandberg@arm.com    assert(!path.empty());
52110905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "Popping: %s\n", path.top());
52210905Sandreas.sandberg@arm.com    path.pop();
52310905Sandreas.sandberg@arm.com}
52410905Sandreas.sandberg@arm.com
52510905Sandreas.sandberg@arm.comvoid
52610905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::pushName(const char *obj_name)
52710905Sandreas.sandberg@arm.com{
52810905Sandreas.sandberg@arm.com    if (path.empty()) {
52910905Sandreas.sandberg@arm.com        path.push(obj_name);
53010905Sandreas.sandberg@arm.com    } else {
53110905Sandreas.sandberg@arm.com        path.push(csprintf("%s.%s", path.top(), obj_name));
53210905Sandreas.sandberg@arm.com    }
53310905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
53410905Sandreas.sandberg@arm.com}
53510905Sandreas.sandberg@arm.com
53610905Sandreas.sandberg@arm.comvoid
53710905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
53810905Sandreas.sandberg@arm.com{
53910905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
54010905Sandreas.sandberg@arm.com            Serializable::currentSection());
54110905Sandreas.sandberg@arm.com    cp << "\n[" << Serializable::currentSection() << "]\n";
542395SN/A}
5432SN/A
5442SN/Avoid
5456225Snate@binkert.orgdebug_serialize(const string &cpt_dir)
5462SN/A{
5472868Sktlim@umich.edu    Serializable::serializeAll(cpt_dir);
5482SN/A}
5492SN/A
5502SN/A
5512SN/A////////////////////////////////////////////////////////////////////////
5522SN/A//
553395SN/A// SerializableClass member definitions
5542SN/A//
5552SN/A////////////////////////////////////////////////////////////////////////
5562SN/A
557395SN/A// Map of class names to SerializableBuilder creation functions.
5582SN/A// Need to make this a pointer so we can force initialization on the
559395SN/A// first reference; otherwise, some SerializableClass constructors
5602SN/A// may be invoked before the classMap constructor.
5616225Snate@binkert.orgmap<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0;
5622SN/A
563395SN/A// SerializableClass constructor: add mapping to classMap
564395SN/ASerializableClass::SerializableClass(const string &className,
5656225Snate@binkert.org                                     CreateFunc createFunc)
5662SN/A{
5672SN/A    if (classMap == NULL)
5686225Snate@binkert.org        classMap = new map<string, SerializableClass::CreateFunc>();
5692SN/A
5702SN/A    if ((*classMap)[className])
5716225Snate@binkert.org        fatal("Error: simulation object class %s redefined\n", className);
5722SN/A
5732SN/A    // add className --> createFunc to class map
5742SN/A    (*classMap)[className] = createFunc;
5752SN/A}
5762SN/A
5772SN/A//
5782SN/A//
579395SN/ASerializable *
58010905Sandreas.sandberg@arm.comSerializableClass::createObject(CheckpointIn &cp, const string &section)
5812SN/A{
582237SN/A    string className;
5832SN/A
58410905Sandreas.sandberg@arm.com    if (!cp.find(section, "type", className)) {
585395SN/A        fatal("Serializable::create: no 'type' entry in section '%s'.\n",
586237SN/A              section);
5872SN/A    }
5882SN/A
589237SN/A    CreateFunc createFunc = (*classMap)[className];
590237SN/A
591237SN/A    if (createFunc == NULL) {
592395SN/A        fatal("Serializable::create: no create function for class '%s'.\n",
593237SN/A              className);
5942SN/A    }
5952SN/A
596395SN/A    Serializable *object = createFunc(cp, section);
5972SN/A
5982SN/A    assert(object != NULL);
5992SN/A
6002SN/A    return object;
6012SN/A}
6022SN/A
60310905Sandreas.sandberg@arm.comconst std::string &
60410905Sandreas.sandberg@arm.comSerializable::currentSection()
60510905Sandreas.sandberg@arm.com{
60610905Sandreas.sandberg@arm.com    assert(!path.empty());
60710905Sandreas.sandberg@arm.com
60810905Sandreas.sandberg@arm.com    return path.top();
60910905Sandreas.sandberg@arm.com}
610237SN/A
611395SN/ASerializable *
61210905Sandreas.sandberg@arm.comSerializable::create(CheckpointIn &cp, const string &section)
613237SN/A{
614395SN/A    Serializable *object = SerializableClass::createObject(cp, section);
61510905Sandreas.sandberg@arm.com    object->unserializeSection(cp, section);
616237SN/A    return object;
617237SN/A}
618237SN/A
619237SN/A
62010905Sandreas.sandberg@arm.comconst char *CheckpointIn::baseFilename = "m5.cpt";
6217491Ssteve.reinhardt@amd.com
62210905Sandreas.sandberg@arm.comstring CheckpointIn::currentDirectory;
6237491Ssteve.reinhardt@amd.com
6247491Ssteve.reinhardt@amd.comstring
62510905Sandreas.sandberg@arm.comCheckpointIn::setDir(const string &name)
6267491Ssteve.reinhardt@amd.com{
6277823Ssteve.reinhardt@amd.com    // use csprintf to insert curTick() into directory name if it
6287491Ssteve.reinhardt@amd.com    // appears to have a format placeholder in it.
6297491Ssteve.reinhardt@amd.com    currentDirectory = (name.find("%") != string::npos) ?
6307823Ssteve.reinhardt@amd.com        csprintf(name, curTick()) : name;
6317491Ssteve.reinhardt@amd.com    if (currentDirectory[currentDirectory.size() - 1] != '/')
6327491Ssteve.reinhardt@amd.com        currentDirectory += "/";
6337491Ssteve.reinhardt@amd.com    return currentDirectory;
6347491Ssteve.reinhardt@amd.com}
6357491Ssteve.reinhardt@amd.com
6367491Ssteve.reinhardt@amd.comstring
63710905Sandreas.sandberg@arm.comCheckpointIn::dir()
6387491Ssteve.reinhardt@amd.com{
6397491Ssteve.reinhardt@amd.com    return currentDirectory;
6407491Ssteve.reinhardt@amd.com}
6417491Ssteve.reinhardt@amd.com
6427491Ssteve.reinhardt@amd.com
64310905Sandreas.sandberg@arm.comCheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
64410453SAndrew.Bardsley@arm.com    : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
645237SN/A{
64610905Sandreas.sandberg@arm.com    string filename = cptDir + "/" + CheckpointIn::baseFilename;
647237SN/A    if (!db->load(filename)) {
648237SN/A        fatal("Can't load checkpoint file '%s'\n", filename);
649237SN/A    }
650237SN/A}
651237SN/A
65210905Sandreas.sandberg@arm.comCheckpointIn::~CheckpointIn()
6539086Sandreas.hansson@arm.com{
6549086Sandreas.hansson@arm.com    delete db;
6559086Sandreas.hansson@arm.com}
656237SN/A
657237SN/Abool
65810905Sandreas.sandberg@arm.comCheckpointIn::find(const string &section, const string &entry, string &value)
659237SN/A{
660237SN/A    return db->find(section, entry, value);
661237SN/A}
662237SN/A
663237SN/A
664237SN/Abool
66510905Sandreas.sandberg@arm.comCheckpointIn::findObj(const string &section, const string &entry,
6664000Ssaidi@eecs.umich.edu                    SimObject *&value)
667237SN/A{
668237SN/A    string path;
669237SN/A
670237SN/A    if (!db->find(section, entry, path))
671237SN/A        return false;
672237SN/A
67310453SAndrew.Bardsley@arm.com    value = objNameResolver.resolveSimObject(path);
6744000Ssaidi@eecs.umich.edu    return true;
675237SN/A}
676304SN/A
677304SN/A
678304SN/Abool
67910905Sandreas.sandberg@arm.comCheckpointIn::sectionExists(const string &section)
680304SN/A{
681304SN/A    return db->sectionExists(section);
682304SN/A}
683