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 ¶m) 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> ¶m) 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> ¶m) 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> ¶m) 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 ¶m) 2348303SAli.Saidi@ARM.com{ 2358303SAli.Saidi@ARM.com const string §ion(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 ¶m, bool warn) 2457202Sgblack@eecs.umich.edu{ 2467202Sgblack@eecs.umich.edu const string §ion(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 §ion(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> ¶m) 3207209Sgblack@eecs.umich.edu{ 3217209Sgblack@eecs.umich.edu const string §ion(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> ¶m) 3627226Sgblack@eecs.umich.edu{ 3637226Sgblack@eecs.umich.edu const string §ion(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> ¶m) 3927226Sgblack@eecs.umich.edu{ 3937226Sgblack@eecs.umich.edu const string §ion(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 * ¶m) 4227232Sgblack@eecs.umich.edu{ 4237226Sgblack@eecs.umich.edu const string §ion(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 ¶m); \ 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> ¶m); \ 4477234Sgblack@eecs.umich.edu template void \ 4487234Sgblack@eecs.umich.edu arrayParamIn(CheckpointIn &cp, const string &name, \ 4497234Sgblack@eecs.umich.edu vector<type> ¶m); \ 4507234Sgblack@eecs.umich.edu template void \ 4517234Sgblack@eecs.umich.edu arrayParamOut(CheckpointOut &os, const string &name, \ 4527234Sgblack@eecs.umich.edu const list<type> ¶m); \ 4537234Sgblack@eecs.umich.edu template void \ 4547234Sgblack@eecs.umich.edu arrayParamIn(CheckpointIn &cp, const string &name, \ 4557234Sgblack@eecs.umich.edu list<type> ¶m); 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 §ion(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 §ion, 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 §ion, 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 §ion) 7257418Sgblack@eecs.umich.edu{ 7267418Sgblack@eecs.umich.edu return db->sectionExists(section); 7278142SAli.Saidi@ARM.com} 7287418Sgblack@eecs.umich.edu