serialize.cc revision 11077
17199Sgblack@eecs.umich.edu/*
27199Sgblack@eecs.umich.edu * Copyright (c) 2015 ARM Limited
311939Snikos.nikoleris@arm.com * All rights reserved
47199Sgblack@eecs.umich.edu *
57199Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
67199Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
77199Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
87199Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
97199Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
107199Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
117199Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
127199Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137199Sgblack@eecs.umich.edu *
147199Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
157199Sgblack@eecs.umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc.
167199Sgblack@eecs.umich.edu * Copyright (c) 2013 Mark D. Hill and David A. Wood
177199Sgblack@eecs.umich.edu * All rights reserved.
187199Sgblack@eecs.umich.edu *
197199Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
207199Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
217199Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
227199Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
237199Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
247199Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
257199Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
267199Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
277199Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
287199Sgblack@eecs.umich.edu * this software without specific prior written permission.
297199Sgblack@eecs.umich.edu *
307199Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
317199Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
327199Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
337199Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
347199Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
357199Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
367199Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
377199Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
387199Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
397199Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
407199Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
417199Sgblack@eecs.umich.edu *
427199Sgblack@eecs.umich.edu * Authors: Nathan Binkert
4310474Sandreas.hansson@arm.com *          Erik Hallnor
4410037SARM gem5 Developers *          Steve Reinhardt
4510037SARM gem5 Developers *          Andreas Sandberg
4610037SARM gem5 Developers */
4710037SARM gem5 Developers
4810037SARM gem5 Developers#include <sys/stat.h>
4910037SARM gem5 Developers#include <sys/time.h>
5010037SARM gem5 Developers#include <sys/types.h>
5110037SARM gem5 Developers
5210037SARM gem5 Developers#include <cerrno>
5310037SARM gem5 Developers#include <fstream>
5410037SARM gem5 Developers#include <list>
5510037SARM gem5 Developers#include <string>
5610037SARM gem5 Developers#include <vector>
5710037SARM gem5 Developers
5810037SARM gem5 Developers#include "base/framebuffer.hh"
5910037SARM gem5 Developers#include "base/inifile.hh"
6010037SARM gem5 Developers#include "base/misc.hh"
6110037SARM gem5 Developers#include "base/output.hh"
6210474Sandreas.hansson@arm.com#include "base/str.hh"
6310474Sandreas.hansson@arm.com#include "base/trace.hh"
6410037SARM gem5 Developers#include "debug/Checkpoint.hh"
6510037SARM gem5 Developers#include "sim/eventq.hh"
6610037SARM gem5 Developers#include "sim/serialize.hh"
6710037SARM gem5 Developers#include "sim/sim_events.hh"
6810474Sandreas.hansson@arm.com#include "sim/sim_exit.hh"
6910037SARM gem5 Developers#include "sim/sim_object.hh"
7010037SARM gem5 Developers
718782Sgblack@eecs.umich.edu// For stat reset hack
7210037SARM gem5 Developers#include "sim/stat_control.hh"
738782Sgblack@eecs.umich.edu
747199Sgblack@eecs.umich.eduusing namespace std;
757199Sgblack@eecs.umich.edu
7610037SARM gem5 Developers//
7710037SARM gem5 Developers// The base implementations use to_number for parsing and '<<' for
788628SAli.Saidi@ARM.com// displaying, suitable for integer types.
7910037SARM gem5 Developers//
8010037SARM gem5 Developerstemplate <class T>
8110037SARM gem5 Developersbool
8210037SARM gem5 DevelopersparseParam(const string &s, T &value)
8310037SARM gem5 Developers{
8410037SARM gem5 Developers    return to_number(s, value);
8510037SARM gem5 Developers}
8610037SARM gem5 Developers
8710037SARM gem5 Developerstemplate <class T>
8810037SARM gem5 Developersvoid
8910037SARM gem5 DevelopersshowParam(CheckpointOut &os, const T &value)
9010037SARM gem5 Developers{
9110037SARM gem5 Developers    os << value;
9210037SARM gem5 Developers}
9310037SARM gem5 Developers
9410474Sandreas.hansson@arm.com//
9510037SARM gem5 Developers// Template specializations:
9610037SARM gem5 Developers// - char (8-bit integer)
9710037SARM gem5 Developers// - floating-point types
9810037SARM gem5 Developers// - bool
9910037SARM gem5 Developers// - string
10010037SARM gem5 Developers//
10110037SARM gem5 Developers
10210037SARM gem5 Developers// Treat 8-bit ints (chars) as ints on output, not as chars
10310037SARM gem5 Developerstemplate <>
10410037SARM gem5 Developersvoid
10510037SARM gem5 DevelopersshowParam(CheckpointOut &os, const char &value)
10610037SARM gem5 Developers{
10710037SARM gem5 Developers    os << (int)value;
10810037SARM gem5 Developers}
10910037SARM gem5 Developers
11010037SARM gem5 Developers
11110037SARM gem5 Developerstemplate <>
11210037SARM gem5 Developersvoid
11310037SARM gem5 DevelopersshowParam(CheckpointOut &os, const signed char &value)
11410037SARM gem5 Developers{
11510037SARM gem5 Developers    os << (int)value;
11610037SARM gem5 Developers}
11710037SARM gem5 Developers
11810037SARM gem5 Developers
11910037SARM gem5 Developerstemplate <>
12010037SARM gem5 Developersvoid
12110037SARM gem5 DevelopersshowParam(CheckpointOut &os, const unsigned char &value)
12210037SARM gem5 Developers{
12310037SARM gem5 Developers    os << (unsigned int)value;
12410037SARM gem5 Developers}
12510037SARM gem5 Developers
12610037SARM gem5 Developers
12710037SARM gem5 Developerstemplate <>
12810037SARM gem5 Developersbool
12910037SARM gem5 DevelopersparseParam(const string &s, float &value)
13010037SARM gem5 Developers{
13110037SARM gem5 Developers    return to_number(s, value);
13210037SARM gem5 Developers}
13311355Smitch.hayenga@arm.com
13411355Smitch.hayenga@arm.comtemplate <>
13510037SARM gem5 Developersbool
13610037SARM gem5 DevelopersparseParam(const string &s, double &value)
13710037SARM gem5 Developers{
13810037SARM gem5 Developers    return to_number(s, value);
13910037SARM gem5 Developers}
1407199Sgblack@eecs.umich.edu
1417199Sgblack@eecs.umich.edutemplate <>
1427202Sgblack@eecs.umich.edubool
1437202Sgblack@eecs.umich.eduparseParam(const string &s, bool &value)
1447202Sgblack@eecs.umich.edu{
1457202Sgblack@eecs.umich.edu    return to_bool(s, value);
1467202Sgblack@eecs.umich.edu}
1478301SAli.Saidi@ARM.com
1488303SAli.Saidi@ARM.com// Display bools as strings
1498303SAli.Saidi@ARM.comtemplate <>
1508303SAli.Saidi@ARM.comvoid
1518303SAli.Saidi@ARM.comshowParam(CheckpointOut &os, const bool &value)
1528303SAli.Saidi@ARM.com{
1538303SAli.Saidi@ARM.com    os << (value ? "true" : "false");
1548301SAli.Saidi@ARM.com}
1558301SAli.Saidi@ARM.com
1567202Sgblack@eecs.umich.edu
1577202Sgblack@eecs.umich.edu// String requires no processing to speak of
1587599Sminkyu.jeong@arm.comtemplate <>
1597783SGiacomo.Gabrielli@arm.combool
1607202Sgblack@eecs.umich.eduparseParam(const string &s, string &value)
1617202Sgblack@eecs.umich.edu{
1627202Sgblack@eecs.umich.edu    value = s;
1637202Sgblack@eecs.umich.edu    return true;
1647202Sgblack@eecs.umich.edu}
1657202Sgblack@eecs.umich.edu
1667202Sgblack@eecs.umich.eduint Serializable::ckptMaxCount = 0;
1677599Sminkyu.jeong@arm.comint Serializable::ckptCount = 0;
1687783SGiacomo.Gabrielli@arm.comint Serializable::ckptPrevCount = -1;
1697202Sgblack@eecs.umich.edustd::stack<std::string> Serializable::path;
1707202Sgblack@eecs.umich.edu
1717202Sgblack@eecs.umich.edutemplate <class T>
1727202Sgblack@eecs.umich.eduvoid
17310037SARM gem5 DevelopersparamOut(CheckpointOut &os, const string &name, const T &param)
17410037SARM gem5 Developers{
17510037SARM gem5 Developers    os << name << "=";
17610037SARM gem5 Developers    showParam(os, param);
17710037SARM gem5 Developers    os << "\n";
17810037SARM gem5 Developers}
17910037SARM gem5 Developers
18010037SARM gem5 Developerstemplate <class T>
18110037SARM gem5 Developersvoid
18210037SARM gem5 DevelopersarrayParamOut(CheckpointOut &os, const string &name, const vector<T> &param)
18310037SARM gem5 Developers{
18410474Sandreas.hansson@arm.com    typename vector<T>::size_type size = param.size();
18510474Sandreas.hansson@arm.com    os << name << "=";
18610037SARM gem5 Developers    if (size > 0)
18710037SARM gem5 Developers        showParam(os, param[0]);
18810037SARM gem5 Developers    for (typename vector<T>::size_type i = 1; i < size; ++i) {
18910037SARM gem5 Developers        os << " ";
19010037SARM gem5 Developers        showParam(os, param[i]);
19110037SARM gem5 Developers    }
19210037SARM gem5 Developers    os << "\n";
19310037SARM gem5 Developers}
19410037SARM gem5 Developers
19510037SARM gem5 Developerstemplate <class T>
19610037SARM gem5 Developersvoid
19710037SARM gem5 DevelopersarrayParamOut(CheckpointOut &os, const string &name, const list<T> &param)
19810037SARM gem5 Developers{
19910037SARM gem5 Developers    typename list<T>::const_iterator it = param.begin();
20010037SARM gem5 Developers
20110037SARM gem5 Developers    os << name << "=";
20210037SARM gem5 Developers    if (param.size() > 0)
20310037SARM gem5 Developers        showParam(os, *it);
20410037SARM gem5 Developers    it++;
20510037SARM gem5 Developers    while (it != param.end()) {
20610037SARM gem5 Developers        os << " ";
20710037SARM gem5 Developers        showParam(os, *it);
20810037SARM gem5 Developers        it++;
20910037SARM gem5 Developers    }
21010037SARM gem5 Developers    os << "\n";
21110037SARM gem5 Developers}
21210037SARM gem5 Developers
21310037SARM gem5 Developerstemplate <class T>
21410037SARM gem5 Developersvoid
21510037SARM gem5 DevelopersarrayParamOut(CheckpointOut &os, const string &name, const set<T> &param)
21610474Sandreas.hansson@arm.com{
21710474Sandreas.hansson@arm.com    typename set<T>::const_iterator it = param.begin();
21810037SARM gem5 Developers
21910037SARM gem5 Developers    os << name << "=";
22010037SARM gem5 Developers    if (param.size() > 0)
22110037SARM gem5 Developers        showParam(os, *it);
22210037SARM gem5 Developers    it++;
22310501Sakash.bagdia@ARM.com    while (it != param.end()) {
22410037SARM gem5 Developers        os << " ";
22510037SARM gem5 Developers        showParam(os, *it);
22610037SARM gem5 Developers        it++;
22710037SARM gem5 Developers    }
2287202Sgblack@eecs.umich.edu    os << "\n";
2297400SAli.Saidi@ARM.com}
2308303SAli.Saidi@ARM.com
2318303SAli.Saidi@ARM.comtemplate <class T>
2328303SAli.Saidi@ARM.comvoid
2338303SAli.Saidi@ARM.comparamIn(CheckpointIn &cp, const string &name, T &param)
2348303SAli.Saidi@ARM.com{
2358303SAli.Saidi@ARM.com    const string &section(Serializable::currentSection());
2368303SAli.Saidi@ARM.com    string str;
23710037SARM gem5 Developers    if (!cp.find(section, name, str) || !parseParam(str, param)) {
23810037SARM gem5 Developers        fatal("Can't unserialize '%s:%s'\n", section, name);
2398303SAli.Saidi@ARM.com    }
2408303SAli.Saidi@ARM.com}
2418303SAli.Saidi@ARM.com
2428303SAli.Saidi@ARM.comtemplate <class T>
2438303SAli.Saidi@ARM.combool
2447202Sgblack@eecs.umich.eduoptParamIn(CheckpointIn &cp, const string &name, T &param, bool warn)
2457202Sgblack@eecs.umich.edu{
2467202Sgblack@eecs.umich.edu    const string &section(Serializable::currentSection());
2477599Sminkyu.jeong@arm.com    string str;
2487599Sminkyu.jeong@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
2497202Sgblack@eecs.umich.edu        if (warn)
2507202Sgblack@eecs.umich.edu            warn("optional parameter %s:%s not present\n", section, name);
2517202Sgblack@eecs.umich.edu        return false;
2527202Sgblack@eecs.umich.edu    } else {
2537202Sgblack@eecs.umich.edu        return true;
2547202Sgblack@eecs.umich.edu    }
2557202Sgblack@eecs.umich.edu}
2567599Sminkyu.jeong@arm.com
2577599Sminkyu.jeong@arm.comtemplate <class T>
2587202Sgblack@eecs.umich.eduvoid
2597202Sgblack@eecs.umich.eduarrayParamOut(CheckpointOut &os, const string &name,
2607202Sgblack@eecs.umich.edu              const T *param, unsigned size)
2617202Sgblack@eecs.umich.edu{
2627202Sgblack@eecs.umich.edu    os << name << "=";
2637400SAli.Saidi@ARM.com    if (size > 0)
2648303SAli.Saidi@ARM.com        showParam(os, param[0]);
2658303SAli.Saidi@ARM.com    for (unsigned i = 1; i < size; ++i) {
2668303SAli.Saidi@ARM.com        os << " ";
2678303SAli.Saidi@ARM.com        showParam(os, param[i]);
2688303SAli.Saidi@ARM.com    }
2698303SAli.Saidi@ARM.com    os << "\n";
27010037SARM gem5 Developers}
27110037SARM gem5 Developers
2728303SAli.Saidi@ARM.com
2738303SAli.Saidi@ARM.comtemplate <class T>
2748303SAli.Saidi@ARM.comvoid
2758303SAli.Saidi@ARM.comarrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
2768303SAli.Saidi@ARM.com{
2777202Sgblack@eecs.umich.edu    const string &section(Serializable::currentSection());
2787202Sgblack@eecs.umich.edu    string str;
2797202Sgblack@eecs.umich.edu    if (!cp.find(section, name, str)) {
2807599Sminkyu.jeong@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
2817599Sminkyu.jeong@arm.com    }
2827202Sgblack@eecs.umich.edu
2837202Sgblack@eecs.umich.edu    // code below stolen from VectorParam<T>::parse().
2847202Sgblack@eecs.umich.edu    // it would be nice to unify these somehow...
2857202Sgblack@eecs.umich.edu
2867202Sgblack@eecs.umich.edu    vector<string> tokens;
2877202Sgblack@eecs.umich.edu
2887202Sgblack@eecs.umich.edu    tokenize(tokens, str, ' ');
2897599Sminkyu.jeong@arm.com
2907599Sminkyu.jeong@arm.com    // Need this if we were doing a vector
2917202Sgblack@eecs.umich.edu    // value.resize(tokens.size());
2927202Sgblack@eecs.umich.edu
2937202Sgblack@eecs.umich.edu    if (tokens.size() != size) {
2947209Sgblack@eecs.umich.edu        fatal("Array size mismatch on %s:%s'\n", section, name);
2957209Sgblack@eecs.umich.edu    }
2967209Sgblack@eecs.umich.edu
2977209Sgblack@eecs.umich.edu    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
2987209Sgblack@eecs.umich.edu        // need to parse into local variable to handle vector<bool>,
2997261Sgblack@eecs.umich.edu        // for which operator[] returns a special reference class
3007209Sgblack@eecs.umich.edu        // that's not the same as 'bool&', (since it's a packed
3017209Sgblack@eecs.umich.edu        // vector)
3027261Sgblack@eecs.umich.edu        T scalar_value;
3037261Sgblack@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
3047209Sgblack@eecs.umich.edu            string err("could not parse \"");
3057209Sgblack@eecs.umich.edu
3067209Sgblack@eecs.umich.edu            err += str;
3077209Sgblack@eecs.umich.edu            err += "\"";
3087209Sgblack@eecs.umich.edu
3097209Sgblack@eecs.umich.edu            fatal(err);
3107209Sgblack@eecs.umich.edu        }
3117209Sgblack@eecs.umich.edu
3127209Sgblack@eecs.umich.edu        // assign parsed value to vector
3137261Sgblack@eecs.umich.edu        param[i] = scalar_value;
3147209Sgblack@eecs.umich.edu    }
3157209Sgblack@eecs.umich.edu}
3167261Sgblack@eecs.umich.edu
3177261Sgblack@eecs.umich.edutemplate <class T>
3187209Sgblack@eecs.umich.eduvoid
3197209Sgblack@eecs.umich.eduarrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
3207209Sgblack@eecs.umich.edu{
3217209Sgblack@eecs.umich.edu    const string &section(Serializable::currentSection());
3227209Sgblack@eecs.umich.edu    string str;
3237209Sgblack@eecs.umich.edu    if (!cp.find(section, name, str)) {
3247261Sgblack@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
3257209Sgblack@eecs.umich.edu    }
3267209Sgblack@eecs.umich.edu
3277261Sgblack@eecs.umich.edu    // code below stolen from VectorParam<T>::parse().
3287261Sgblack@eecs.umich.edu    // it would be nice to unify these somehow...
3297209Sgblack@eecs.umich.edu
3307226Sgblack@eecs.umich.edu    vector<string> tokens;
3317249Sgblack@eecs.umich.edu
3327249Sgblack@eecs.umich.edu    tokenize(tokens, str, ' ');
3337249Sgblack@eecs.umich.edu
3347249Sgblack@eecs.umich.edu    // Need this if we were doing a vector
3357249Sgblack@eecs.umich.edu    // value.resize(tokens.size());
3367249Sgblack@eecs.umich.edu
3377249Sgblack@eecs.umich.edu    param.resize(tokens.size());
3387249Sgblack@eecs.umich.edu
3397249Sgblack@eecs.umich.edu    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
3407249Sgblack@eecs.umich.edu        // need to parse into local variable to handle vector<bool>,
3417249Sgblack@eecs.umich.edu        // for which operator[] returns a special reference class
3427249Sgblack@eecs.umich.edu        // that's not the same as 'bool&', (since it's a packed
3437249Sgblack@eecs.umich.edu        // vector)
3447261Sgblack@eecs.umich.edu        T scalar_value;
3457249Sgblack@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
3467249Sgblack@eecs.umich.edu            string err("could not parse \"");
3477261Sgblack@eecs.umich.edu
3487261Sgblack@eecs.umich.edu            err += str;
3497249Sgblack@eecs.umich.edu            err += "\"";
3507249Sgblack@eecs.umich.edu
3517251Sgblack@eecs.umich.edu            fatal(err);
3527251Sgblack@eecs.umich.edu        }
3537251Sgblack@eecs.umich.edu
3547261Sgblack@eecs.umich.edu        // assign parsed value to vector
3557251Sgblack@eecs.umich.edu        param[i] = scalar_value;
3567251Sgblack@eecs.umich.edu    }
3577261Sgblack@eecs.umich.edu}
3587261Sgblack@eecs.umich.edu
3597251Sgblack@eecs.umich.edutemplate <class T>
3607251Sgblack@eecs.umich.eduvoid
3617226Sgblack@eecs.umich.eduarrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
3627226Sgblack@eecs.umich.edu{
3637226Sgblack@eecs.umich.edu    const string &section(Serializable::currentSection());
3647232Sgblack@eecs.umich.edu    string str;
3658302SAli.Saidi@ARM.com    if (!cp.find(section, name, str)) {
3667226Sgblack@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
3677226Sgblack@eecs.umich.edu    }
3687232Sgblack@eecs.umich.edu    param.clear();
3697226Sgblack@eecs.umich.edu
3708304SAli.Saidi@ARM.com    vector<string> tokens;
3717232Sgblack@eecs.umich.edu    tokenize(tokens, str, ' ');
3727232Sgblack@eecs.umich.edu
3737226Sgblack@eecs.umich.edu    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
3747226Sgblack@eecs.umich.edu        T scalar_value;
3757226Sgblack@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
3767226Sgblack@eecs.umich.edu            string err("could not parse \"");
3777226Sgblack@eecs.umich.edu
3787232Sgblack@eecs.umich.edu            err += str;
3798302SAli.Saidi@ARM.com            err += "\"";
3807226Sgblack@eecs.umich.edu
3817226Sgblack@eecs.umich.edu            fatal(err);
3827232Sgblack@eecs.umich.edu        }
3837226Sgblack@eecs.umich.edu
3848304SAli.Saidi@ARM.com        // assign parsed value to vector
3857232Sgblack@eecs.umich.edu        param.push_back(scalar_value);
3867232Sgblack@eecs.umich.edu    }
3877226Sgblack@eecs.umich.edu}
3887226Sgblack@eecs.umich.edu
3897226Sgblack@eecs.umich.edutemplate <class T>
3907226Sgblack@eecs.umich.eduvoid
3917226Sgblack@eecs.umich.eduarrayParamIn(CheckpointIn &cp, const string &name, set<T> &param)
3927226Sgblack@eecs.umich.edu{
3937226Sgblack@eecs.umich.edu    const string &section(Serializable::currentSection());
3947232Sgblack@eecs.umich.edu    string str;
3958302SAli.Saidi@ARM.com    if (!cp.find(section, name, str)) {
3967226Sgblack@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
3977232Sgblack@eecs.umich.edu    }
3988302SAli.Saidi@ARM.com    param.clear();
3997226Sgblack@eecs.umich.edu
4007226Sgblack@eecs.umich.edu    vector<string> tokens;
4017226Sgblack@eecs.umich.edu    tokenize(tokens, str, ' ');
4027232Sgblack@eecs.umich.edu
4037226Sgblack@eecs.umich.edu    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
4048304SAli.Saidi@ARM.com        T scalar_value;
4057232Sgblack@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
4067232Sgblack@eecs.umich.edu            string err("could not parse \"");
4077226Sgblack@eecs.umich.edu
4087226Sgblack@eecs.umich.edu            err += str;
4097226Sgblack@eecs.umich.edu            err += "\"";
4107226Sgblack@eecs.umich.edu
4117226Sgblack@eecs.umich.edu            fatal(err);
4127226Sgblack@eecs.umich.edu        }
4137226Sgblack@eecs.umich.edu
4147232Sgblack@eecs.umich.edu        // assign parsed value to vector
4158302SAli.Saidi@ARM.com        param.insert(scalar_value);
4167226Sgblack@eecs.umich.edu    }
4177232Sgblack@eecs.umich.edu}
4188302SAli.Saidi@ARM.com
4197226Sgblack@eecs.umich.edu
4207226Sgblack@eecs.umich.eduvoid
4217226Sgblack@eecs.umich.eduobjParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
4227232Sgblack@eecs.umich.edu{
4237226Sgblack@eecs.umich.edu    const string &section(Serializable::currentSection());
4248304SAli.Saidi@ARM.com    if (!cp.findObj(section, name, param)) {
4257232Sgblack@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
4267232Sgblack@eecs.umich.edu    }
4277226Sgblack@eecs.umich.edu}
4287234Sgblack@eecs.umich.edu
4297234Sgblack@eecs.umich.edu
4307234Sgblack@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type)                               \
4318588Sgblack@eecs.umich.edu    template void                                                       \
4327234Sgblack@eecs.umich.edu    paramOut(CheckpointOut &os, const string &name, type const &param); \
4337234Sgblack@eecs.umich.edu    template void                                                       \
4347234Sgblack@eecs.umich.edu    paramIn(CheckpointIn &cp, const string &name, type & param);        \
4357234Sgblack@eecs.umich.edu    template bool                                                       \
4367234Sgblack@eecs.umich.edu    optParamIn(CheckpointIn &cp, const string &name, type & param,      \
4377234Sgblack@eecs.umich.edu               bool warn);                                              \
4387234Sgblack@eecs.umich.edu    template void                                                       \
4397234Sgblack@eecs.umich.edu    arrayParamOut(CheckpointOut &os, const string &name,                \
4408588Sgblack@eecs.umich.edu                  type const *param, unsigned size);                    \
4417234Sgblack@eecs.umich.edu    template void                                                       \
4427234Sgblack@eecs.umich.edu    arrayParamIn(CheckpointIn &cp, const string &name,                  \
4437234Sgblack@eecs.umich.edu                 type *param, unsigned size);                           \
4447234Sgblack@eecs.umich.edu    template void                                                       \
4457234Sgblack@eecs.umich.edu    arrayParamOut(CheckpointOut &os, const string &name,                \
4467234Sgblack@eecs.umich.edu                  const vector<type> &param);                           \
4477234Sgblack@eecs.umich.edu    template void                                                       \
4487234Sgblack@eecs.umich.edu    arrayParamIn(CheckpointIn &cp, const string &name,                  \
4497234Sgblack@eecs.umich.edu                 vector<type> &param);                                  \
4507234Sgblack@eecs.umich.edu    template void                                                       \
4517234Sgblack@eecs.umich.edu    arrayParamOut(CheckpointOut &os, const string &name,                \
4527234Sgblack@eecs.umich.edu                  const list<type> &param);                             \
4537234Sgblack@eecs.umich.edu    template void                                                       \
4547234Sgblack@eecs.umich.edu    arrayParamIn(CheckpointIn &cp, const string &name,                  \
4557234Sgblack@eecs.umich.edu                 list<type> &param);
4567234Sgblack@eecs.umich.edu
4577234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(char)
4587234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(signed char)
4597234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(unsigned char)
4607234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(signed short)
4617234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(unsigned short)
4627234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(signed int)
4637234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(unsigned int)
4647234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(signed long)
4657234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(unsigned long)
4667234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(signed long long)
4677234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(unsigned long long)
4687234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(bool)
4697234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(float)
4707234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(double)
4717234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(string)
4727234Sgblack@eecs.umich.eduINSTANTIATE_PARAM_TEMPLATES(Pixel)
4737234Sgblack@eecs.umich.edu
4747234Sgblack@eecs.umich.edu// set is only used with strings and furthermore doesn't agree with Pixel
4757234Sgblack@eecs.umich.edutemplate void
4767234Sgblack@eecs.umich.eduarrayParamOut(CheckpointOut &, const string &, const set<string> &);
4777234Sgblack@eecs.umich.edutemplate void
4787234Sgblack@eecs.umich.eduarrayParamIn(CheckpointIn &, const string &, set<string> &);
4797234Sgblack@eecs.umich.edu
4807234Sgblack@eecs.umich.edu/////////////////////////////
4817234Sgblack@eecs.umich.edu
4827234Sgblack@eecs.umich.edu/// Container for serializing global variables (not associated with
4837234Sgblack@eecs.umich.edu/// any serialized object).
4847234Sgblack@eecs.umich.educlass Globals : public Serializable
4857234Sgblack@eecs.umich.edu{
4867234Sgblack@eecs.umich.edu  public:
4877234Sgblack@eecs.umich.edu    Globals()
4887234Sgblack@eecs.umich.edu        : unserializedCurTick(0) {}
4897234Sgblack@eecs.umich.edu
4907234Sgblack@eecs.umich.edu    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
4917234Sgblack@eecs.umich.edu    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
4927234Sgblack@eecs.umich.edu
4937234Sgblack@eecs.umich.edu    Tick unserializedCurTick;
4947234Sgblack@eecs.umich.edu};
4957234Sgblack@eecs.umich.edu
4967234Sgblack@eecs.umich.edu/// The one and only instance of the Globals class.
4977234Sgblack@eecs.umich.eduGlobals globals;
4987234Sgblack@eecs.umich.edu
4997234Sgblack@eecs.umich.edu/// The version tags for this build of the simulator, to be stored in the
5007234Sgblack@eecs.umich.edu/// Globals section during serialization and compared upon unserialization.
5017234Sgblack@eecs.umich.eduextern std::set<std::string> version_tags;
5027234Sgblack@eecs.umich.edu
5038588Sgblack@eecs.umich.eduvoid
5047234Sgblack@eecs.umich.eduGlobals::serialize(CheckpointOut &cp) const
5057234Sgblack@eecs.umich.edu{
5067234Sgblack@eecs.umich.edu    paramOut(cp, "curTick", curTick());
5077234Sgblack@eecs.umich.edu    SERIALIZE_CONTAINER(version_tags);
5087234Sgblack@eecs.umich.edu}
5097234Sgblack@eecs.umich.edu
5107234Sgblack@eecs.umich.eduvoid
5118588Sgblack@eecs.umich.eduGlobals::unserialize(CheckpointIn &cp)
5127234Sgblack@eecs.umich.edu{
5137234Sgblack@eecs.umich.edu    paramIn(cp, "curTick", unserializedCurTick);
5147234Sgblack@eecs.umich.edu
5157234Sgblack@eecs.umich.edu    const std::string &section(Serializable::currentSection());
5167234Sgblack@eecs.umich.edu    std::string str;
5177234Sgblack@eecs.umich.edu    if (!cp.find(section, "version_tags", str)) {
5187234Sgblack@eecs.umich.edu        warn("**********************************************************\n");
5197234Sgblack@eecs.umich.edu        warn("!!!! Checkpoint uses an old versioning scheme.        !!!!\n");
5207234Sgblack@eecs.umich.edu        warn("Run the checkpoint upgrader (util/cpt_upgrader.py) on your "
5217234Sgblack@eecs.umich.edu             "checkpoint\n");
5227234Sgblack@eecs.umich.edu        warn("**********************************************************\n");
5237234Sgblack@eecs.umich.edu        return;
5247234Sgblack@eecs.umich.edu    }
5257234Sgblack@eecs.umich.edu
5267234Sgblack@eecs.umich.edu    std::set<std::string> cpt_tags;
5277234Sgblack@eecs.umich.edu    arrayParamIn(cp, "version_tags", cpt_tags); // UNSERIALIZE_CONTAINER
5287234Sgblack@eecs.umich.edu
5297234Sgblack@eecs.umich.edu    bool err = false;
5307234Sgblack@eecs.umich.edu    for (const auto& t : version_tags) {
5317234Sgblack@eecs.umich.edu        if (cpt_tags.find(t) == cpt_tags.end()) {
5327234Sgblack@eecs.umich.edu            // checkpoint is missing tag that this binary has
5337234Sgblack@eecs.umich.edu            if (!err) {
5347234Sgblack@eecs.umich.edu                warn("*****************************************************\n");
5357234Sgblack@eecs.umich.edu                warn("!!!! Checkpoint is missing the following version tags:\n");
5367234Sgblack@eecs.umich.edu                err = true;
5377234Sgblack@eecs.umich.edu            }
5387234Sgblack@eecs.umich.edu            warn("  %s\n", t);
5397234Sgblack@eecs.umich.edu        }
5407234Sgblack@eecs.umich.edu    }
5417234Sgblack@eecs.umich.edu    if (err) {
5427234Sgblack@eecs.umich.edu        warn("You might experience some issues when restoring and should run "
5437234Sgblack@eecs.umich.edu             "the checkpoint upgrader (util/cpt_upgrader.py) on your "
5447234Sgblack@eecs.umich.edu             "checkpoint\n");
5457234Sgblack@eecs.umich.edu        warn("**********************************************************\n");
5467234Sgblack@eecs.umich.edu    }
5477234Sgblack@eecs.umich.edu
5487234Sgblack@eecs.umich.edu    err = false;
5497234Sgblack@eecs.umich.edu    for (const auto& t : cpt_tags) {
5507234Sgblack@eecs.umich.edu        if (version_tags.find(t) == version_tags.end()) {
5517234Sgblack@eecs.umich.edu            // gem5 binary is missing tag that this checkpoint has
5527234Sgblack@eecs.umich.edu            if (!err) {
5537234Sgblack@eecs.umich.edu                warn("*****************************************************\n");
5547234Sgblack@eecs.umich.edu                warn("!!!! gem5 is missing the following version tags:\n");
5557234Sgblack@eecs.umich.edu                err = true;
5567234Sgblack@eecs.umich.edu            }
5577234Sgblack@eecs.umich.edu            warn("  %s\n", t);
5587234Sgblack@eecs.umich.edu        }
5597234Sgblack@eecs.umich.edu    }
5607234Sgblack@eecs.umich.edu    if (err) {
5617234Sgblack@eecs.umich.edu        warn("Running a checkpoint with incompatible version tags is not "
5627234Sgblack@eecs.umich.edu             "supported. While it might work, you may experience incorrect "
5637234Sgblack@eecs.umich.edu             "behavior or crashes.\n");
5647234Sgblack@eecs.umich.edu        warn("**********************************************************\n");
5657234Sgblack@eecs.umich.edu     }
5667234Sgblack@eecs.umich.edu}
5677234Sgblack@eecs.umich.edu
5687234Sgblack@eecs.umich.eduSerializable::Serializable()
5697234Sgblack@eecs.umich.edu{
5707239Sgblack@eecs.umich.edu}
5717239Sgblack@eecs.umich.edu
5727239Sgblack@eecs.umich.eduSerializable::~Serializable()
5737239Sgblack@eecs.umich.edu{
5747239Sgblack@eecs.umich.edu}
5757239Sgblack@eecs.umich.edu
5767239Sgblack@eecs.umich.eduvoid
5778303SAli.Saidi@ARM.comSerializable::serializeSection(CheckpointOut &cp, const char *name) const
5787239Sgblack@eecs.umich.edu{
5797239Sgblack@eecs.umich.edu    Serializable::ScopedCheckpointSection sec(cp, name);
5807239Sgblack@eecs.umich.edu    serialize(cp);
5817239Sgblack@eecs.umich.edu}
5827239Sgblack@eecs.umich.edu
5837239Sgblack@eecs.umich.eduvoid
5848303SAli.Saidi@ARM.comSerializable::serializeSectionOld(CheckpointOut &cp, const char *name)
5857239Sgblack@eecs.umich.edu{
5867239Sgblack@eecs.umich.edu    Serializable::ScopedCheckpointSection sec(cp, name);
5877239Sgblack@eecs.umich.edu    serializeOld(cp);
5887242Sgblack@eecs.umich.edu}
5897242Sgblack@eecs.umich.edu
5907242Sgblack@eecs.umich.eduvoid
5917242Sgblack@eecs.umich.eduSerializable::unserializeSection(CheckpointIn &cp, const char *name)
5927242Sgblack@eecs.umich.edu{
5937242Sgblack@eecs.umich.edu    Serializable::ScopedCheckpointSection sec(cp, name);
5947242Sgblack@eecs.umich.edu    unserialize(cp);
5957242Sgblack@eecs.umich.edu}
5967242Sgblack@eecs.umich.edu
5977242Sgblack@eecs.umich.eduvoid
5987242Sgblack@eecs.umich.eduSerializable::serializeAll(const string &cpt_dir)
5997242Sgblack@eecs.umich.edu{
6007242Sgblack@eecs.umich.edu    string dir = CheckpointIn::setDir(cpt_dir);
6017242Sgblack@eecs.umich.edu    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
6027242Sgblack@eecs.umich.edu            fatal("couldn't mkdir %s\n", dir);
6037242Sgblack@eecs.umich.edu
6047242Sgblack@eecs.umich.edu    string cpt_file = dir + CheckpointIn::baseFilename;
6057242Sgblack@eecs.umich.edu    ofstream outstream(cpt_file.c_str());
6067242Sgblack@eecs.umich.edu    time_t t = time(NULL);
6077242Sgblack@eecs.umich.edu    if (!outstream.is_open())
6087242Sgblack@eecs.umich.edu        fatal("Unable to open file %s for writing\n", cpt_file.c_str());
6097242Sgblack@eecs.umich.edu    outstream << "## checkpoint generated: " << ctime(&t);
6107242Sgblack@eecs.umich.edu
6117242Sgblack@eecs.umich.edu    globals.serializeSection(outstream, "Globals");
6127242Sgblack@eecs.umich.edu
6137242Sgblack@eecs.umich.edu    SimObject::serializeAll(outstream);
6147242Sgblack@eecs.umich.edu}
6157242Sgblack@eecs.umich.edu
6167242Sgblack@eecs.umich.eduvoid
6177242Sgblack@eecs.umich.eduSerializable::unserializeGlobals(CheckpointIn &cp)
6187242Sgblack@eecs.umich.edu{
6197242Sgblack@eecs.umich.edu    globals.unserializeSection(cp, "Globals");
6207242Sgblack@eecs.umich.edu
6217242Sgblack@eecs.umich.edu    for (uint32_t i = 0; i < numMainEventQueues; ++i)
6227242Sgblack@eecs.umich.edu        mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
6237242Sgblack@eecs.umich.edu}
6247247Sgblack@eecs.umich.edu
62510474Sandreas.hansson@arm.comSerializable::ScopedCheckpointSection::~ScopedCheckpointSection()
6267848SAli.Saidi@ARM.com{
6277410Sgblack@eecs.umich.edu    assert(!path.empty());
6287410Sgblack@eecs.umich.edu    DPRINTF(Checkpoint, "Popping: %s\n", path.top());
6297410Sgblack@eecs.umich.edu    path.pop();
6307410Sgblack@eecs.umich.edu}
63110037SARM gem5 Developers
6327247Sgblack@eecs.umich.eduvoid
63310037SARM gem5 DevelopersSerializable::ScopedCheckpointSection::pushName(const char *obj_name)
63410037SARM gem5 Developers{
6357408Sgblack@eecs.umich.edu    if (path.empty()) {
6367418Sgblack@eecs.umich.edu        path.push(obj_name);
6377418Sgblack@eecs.umich.edu    } else {
6387418Sgblack@eecs.umich.edu        path.push(csprintf("%s.%s", path.top(), obj_name));
6397418Sgblack@eecs.umich.edu    }
6407418Sgblack@eecs.umich.edu    DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
6417418Sgblack@eecs.umich.edu}
6427418Sgblack@eecs.umich.edu
64310037SARM gem5 Developersvoid
64410037SARM gem5 DevelopersSerializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
64510037SARM gem5 Developers{
64610037SARM gem5 Developers    DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
64710037SARM gem5 Developers            Serializable::currentSection());
64810037SARM gem5 Developers    cp << "\n[" << Serializable::currentSection() << "]\n";
64910037SARM gem5 Developers}
6508285SPrakash.Ramrakhyani@arm.com
6517418Sgblack@eecs.umich.eduvoid
65210037SARM gem5 Developersdebug_serialize(const string &cpt_dir)
65311150Smitch.hayenga@arm.com{
65411150Smitch.hayenga@arm.com    Serializable::serializeAll(cpt_dir);
65510037SARM gem5 Developers}
65610037SARM gem5 Developers
65710037SARM gem5 Developersconst std::string &
65810474Sandreas.hansson@arm.comSerializable::currentSection()
65910474Sandreas.hansson@arm.com{
66010037SARM gem5 Developers    assert(!path.empty());
66110037SARM gem5 Developers
66210037SARM gem5 Developers    return path.top();
66310037SARM gem5 Developers}
66410474Sandreas.hansson@arm.com
66510474Sandreas.hansson@arm.comconst char *CheckpointIn::baseFilename = "m5.cpt";
66610037SARM gem5 Developers
66710037SARM gem5 Developersstring CheckpointIn::currentDirectory;
66810474Sandreas.hansson@arm.com
66910474Sandreas.hansson@arm.comstring
6708285SPrakash.Ramrakhyani@arm.comCheckpointIn::setDir(const string &name)
67110037SARM gem5 Developers{
6728142SAli.Saidi@ARM.com    // use csprintf to insert curTick() into directory name if it
6737418Sgblack@eecs.umich.edu    // appears to have a format placeholder in it.
6748518Sgeoffrey.blake@arm.com    currentDirectory = (name.find("%") != string::npos) ?
6758518Sgeoffrey.blake@arm.com        csprintf(name, curTick()) : name;
6768518Sgeoffrey.blake@arm.com    if (currentDirectory[currentDirectory.size() - 1] != '/')
6778518Sgeoffrey.blake@arm.com        currentDirectory += "/";
6788518Sgeoffrey.blake@arm.com    return currentDirectory;
6797418Sgblack@eecs.umich.edu}
6808518Sgeoffrey.blake@arm.com
6818518Sgeoffrey.blake@arm.comstring
6828518Sgeoffrey.blake@arm.comCheckpointIn::dir()
6838733Sgeoffrey.blake@arm.com{
6848733Sgeoffrey.blake@arm.com    return currentDirectory;
6857418Sgblack@eecs.umich.edu}
6867418Sgblack@eecs.umich.edu
6878518Sgeoffrey.blake@arm.com
6887418Sgblack@eecs.umich.eduCheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
6897418Sgblack@eecs.umich.edu    : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
69010037SARM gem5 Developers{
69110037SARM gem5 Developers    string filename = cptDir + "/" + CheckpointIn::baseFilename;
69210037SARM gem5 Developers    if (!db->load(filename)) {
69310037SARM gem5 Developers        fatal("Can't load checkpoint file '%s'\n", filename);
69410037SARM gem5 Developers    }
6958285SPrakash.Ramrakhyani@arm.com}
69610037SARM gem5 Developers
69711150Smitch.hayenga@arm.comCheckpointIn::~CheckpointIn()
69811150Smitch.hayenga@arm.com{
69910037SARM gem5 Developers    delete db;
70010037SARM gem5 Developers}
70110037SARM gem5 Developers
70210474Sandreas.hansson@arm.combool
70310474Sandreas.hansson@arm.comCheckpointIn::find(const string &section, const string &entry, string &value)
70410037SARM gem5 Developers{
70510037SARM gem5 Developers    return db->find(section, entry, value);
70610037SARM gem5 Developers}
70710474Sandreas.hansson@arm.com
70810474Sandreas.hansson@arm.com
70910037SARM gem5 Developersbool
71010037SARM gem5 DevelopersCheckpointIn::findObj(const string &section, const string &entry,
71110474Sandreas.hansson@arm.com                    SimObject *&value)
71210474Sandreas.hansson@arm.com{
7138285SPrakash.Ramrakhyani@arm.com    string path;
71410037SARM gem5 Developers
7158285SPrakash.Ramrakhyani@arm.com    if (!db->find(section, entry, path))
71611150Smitch.hayenga@arm.com        return false;
7177418Sgblack@eecs.umich.edu
7187418Sgblack@eecs.umich.edu    value = objNameResolver.resolveSimObject(path);
7197418Sgblack@eecs.umich.edu    return true;
7208733Sgeoffrey.blake@arm.com}
7218733Sgeoffrey.blake@arm.com
7227418Sgblack@eecs.umich.edu
7237418Sgblack@eecs.umich.edubool
7248142SAli.Saidi@ARM.comCheckpointIn::sectionExists(const string &section)
7257418Sgblack@eecs.umich.edu{
7267418Sgblack@eecs.umich.edu    return db->sectionExists(section);
7278142SAli.Saidi@ARM.com}
7287418Sgblack@eecs.umich.edu