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 ¶m) 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> ¶m) 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> ¶m) 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 ¶m) 2152SN/A{ 21610905Sandreas.sandberg@arm.com const string §ion(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 ¶m) 2266820SLisa.Hsu@amd.com{ 22710905Sandreas.sandberg@arm.com const string §ion(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 §ion(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> ¶m) 3004841Ssaidi@eecs.umich.edu{ 30110905Sandreas.sandberg@arm.com const string §ion(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> ¶m) 3427948SAli.Saidi@ARM.com{ 34310905Sandreas.sandberg@arm.com const string §ion(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 * ¶m) 372237SN/A{ 37310905Sandreas.sandberg@arm.com const string §ion(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 ¶m); \ 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> ¶m); \ 39610905Sandreas.sandberg@arm.com template void \ 39710905Sandreas.sandberg@arm.com arrayParamIn(CheckpointIn &cp, const string &name, \ 39810905Sandreas.sandberg@arm.com vector<type> ¶m); \ 39910905Sandreas.sandberg@arm.com template void \ 40010905Sandreas.sandberg@arm.com arrayParamOut(CheckpointOut &os, const string &name, \ 40110905Sandreas.sandberg@arm.com const list<type> ¶m); \ 40210905Sandreas.sandberg@arm.com template void \ 40310905Sandreas.sandberg@arm.com arrayParamIn(CheckpointIn &cp, const string &name, \ 40410905Sandreas.sandberg@arm.com list<type> ¶m); 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 §ion) 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 §ion) 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 §ion, 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 §ion, 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 §ion) 680304SN/A{ 681304SN/A return db->sectionExists(section); 682304SN/A} 683