serialize.cc revision 10907
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 5810907Sandreas.sandberg@arm.com#include "base/framebuffer.hh" 59363SN/A#include "base/inifile.hh" 6056SN/A#include "base/misc.hh" 611388SN/A#include "base/output.hh" 62217SN/A#include "base/str.hh" 63363SN/A#include "base/trace.hh" 6410905Sandreas.sandberg@arm.com#include "debug/Checkpoint.hh" 6556SN/A#include "sim/eventq.hh" 6656SN/A#include "sim/serialize.hh" 6756SN/A#include "sim/sim_events.hh" 681638SN/A#include "sim/sim_exit.hh" 6956SN/A#include "sim/sim_object.hh" 702SN/A 712356SN/A// For stat reset hack 722356SN/A#include "sim/stat_control.hh" 732356SN/A 742SN/Ausing namespace std; 752SN/A 764762Snate@binkert.org// 774762Snate@binkert.org// The base implementations use to_number for parsing and '<<' for 784762Snate@binkert.org// displaying, suitable for integer types. 794762Snate@binkert.org// 804762Snate@binkert.orgtemplate <class T> 814762Snate@binkert.orgbool 824762Snate@binkert.orgparseParam(const string &s, T &value) 834762Snate@binkert.org{ 844762Snate@binkert.org return to_number(s, value); 854762Snate@binkert.org} 864762Snate@binkert.org 874762Snate@binkert.orgtemplate <class T> 884762Snate@binkert.orgvoid 8910905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const T &value) 904762Snate@binkert.org{ 914762Snate@binkert.org os << value; 924762Snate@binkert.org} 934762Snate@binkert.org 944762Snate@binkert.org// 954762Snate@binkert.org// Template specializations: 964762Snate@binkert.org// - char (8-bit integer) 974762Snate@binkert.org// - floating-point types 984762Snate@binkert.org// - bool 994762Snate@binkert.org// - string 1004762Snate@binkert.org// 1014762Snate@binkert.org 1024762Snate@binkert.org// Treat 8-bit ints (chars) as ints on output, not as chars 1034762Snate@binkert.orgtemplate <> 1044762Snate@binkert.orgvoid 10510905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const char &value) 1067494Ssteve.reinhardt@amd.com{ 1077494Ssteve.reinhardt@amd.com os << (int)value; 1087494Ssteve.reinhardt@amd.com} 1097494Ssteve.reinhardt@amd.com 1107494Ssteve.reinhardt@amd.com 1117494Ssteve.reinhardt@amd.comtemplate <> 1127494Ssteve.reinhardt@amd.comvoid 11310905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const signed char &value) 1144762Snate@binkert.org{ 1154762Snate@binkert.org os << (int)value; 1164762Snate@binkert.org} 1174762Snate@binkert.org 1184762Snate@binkert.org 1194762Snate@binkert.orgtemplate <> 1204762Snate@binkert.orgvoid 12110905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const unsigned char &value) 1224762Snate@binkert.org{ 1234762Snate@binkert.org os << (unsigned int)value; 1244762Snate@binkert.org} 1254762Snate@binkert.org 1264762Snate@binkert.org 1274762Snate@binkert.orgtemplate <> 1284762Snate@binkert.orgbool 1294762Snate@binkert.orgparseParam(const string &s, float &value) 1304762Snate@binkert.org{ 13110386Sandreas.hansson@arm.com return to_number(s, value); 1324762Snate@binkert.org} 1334762Snate@binkert.org 1344762Snate@binkert.orgtemplate <> 1354762Snate@binkert.orgbool 1364762Snate@binkert.orgparseParam(const string &s, double &value) 1374762Snate@binkert.org{ 13810386Sandreas.hansson@arm.com return to_number(s, value); 1394762Snate@binkert.org} 1404762Snate@binkert.org 1414762Snate@binkert.orgtemplate <> 1424762Snate@binkert.orgbool 1434762Snate@binkert.orgparseParam(const string &s, bool &value) 1444762Snate@binkert.org{ 14510386Sandreas.hansson@arm.com return to_bool(s, value); 1464762Snate@binkert.org} 1474762Snate@binkert.org 1484762Snate@binkert.org// Display bools as strings 1494762Snate@binkert.orgtemplate <> 1504762Snate@binkert.orgvoid 15110905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const bool &value) 1524762Snate@binkert.org{ 1534762Snate@binkert.org os << (value ? "true" : "false"); 1544762Snate@binkert.org} 1554762Snate@binkert.org 1564762Snate@binkert.org 1574762Snate@binkert.org// String requires no processing to speak of 1584762Snate@binkert.orgtemplate <> 1594762Snate@binkert.orgbool 1604762Snate@binkert.orgparseParam(const string &s, string &value) 1614762Snate@binkert.org{ 1624762Snate@binkert.org value = s; 1634762Snate@binkert.org return true; 1644762Snate@binkert.org} 1654762Snate@binkert.org 1662287SN/Aint Serializable::ckptMaxCount = 0; 1672287SN/Aint Serializable::ckptCount = 0; 1682287SN/Aint Serializable::ckptPrevCount = -1; 16910905Sandreas.sandberg@arm.comstd::stack<std::string> Serializable::path; 1702SN/A 171217SN/Atemplate <class T> 1722SN/Avoid 17310905Sandreas.sandberg@arm.comparamOut(CheckpointOut &os, const string &name, const T ¶m) 1742SN/A{ 175217SN/A os << name << "="; 176217SN/A showParam(os, param); 177217SN/A os << "\n"; 1782SN/A} 1792SN/A 1804841Ssaidi@eecs.umich.edutemplate <class T> 1814841Ssaidi@eecs.umich.eduvoid 18210905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name, const vector<T> ¶m) 1834841Ssaidi@eecs.umich.edu{ 1846227Snate@binkert.org typename vector<T>::size_type size = param.size(); 1854841Ssaidi@eecs.umich.edu os << name << "="; 1864841Ssaidi@eecs.umich.edu if (size > 0) 1874841Ssaidi@eecs.umich.edu showParam(os, param[0]); 1886227Snate@binkert.org for (typename vector<T>::size_type i = 1; i < size; ++i) { 1894841Ssaidi@eecs.umich.edu os << " "; 1904841Ssaidi@eecs.umich.edu showParam(os, param[i]); 1914841Ssaidi@eecs.umich.edu } 1924841Ssaidi@eecs.umich.edu os << "\n"; 1934841Ssaidi@eecs.umich.edu} 1944841Ssaidi@eecs.umich.edu 1957948SAli.Saidi@ARM.comtemplate <class T> 1967948SAli.Saidi@ARM.comvoid 19710905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name, const list<T> ¶m) 1987948SAli.Saidi@ARM.com{ 1997948SAli.Saidi@ARM.com typename list<T>::const_iterator it = param.begin(); 2007948SAli.Saidi@ARM.com 2017948SAli.Saidi@ARM.com os << name << "="; 2027948SAli.Saidi@ARM.com if (param.size() > 0) 2037948SAli.Saidi@ARM.com showParam(os, *it); 2047948SAli.Saidi@ARM.com it++; 2057948SAli.Saidi@ARM.com while (it != param.end()) { 2067948SAli.Saidi@ARM.com os << " "; 2077948SAli.Saidi@ARM.com showParam(os, *it); 2087948SAli.Saidi@ARM.com it++; 2097948SAli.Saidi@ARM.com } 2107948SAli.Saidi@ARM.com os << "\n"; 2117948SAli.Saidi@ARM.com} 212217SN/A 213217SN/Atemplate <class T> 214217SN/Avoid 21510905Sandreas.sandberg@arm.comparamIn(CheckpointIn &cp, const string &name, T ¶m) 2162SN/A{ 21710905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 2186225Snate@binkert.org string str; 21910905Sandreas.sandberg@arm.com if (!cp.find(section, name, str) || !parseParam(str, param)) { 220217SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 221217SN/A } 2222SN/A} 2232SN/A 2246820SLisa.Hsu@amd.comtemplate <class T> 2256820SLisa.Hsu@amd.combool 22610905Sandreas.sandberg@arm.comoptParamIn(CheckpointIn &cp, const string &name, T ¶m) 2276820SLisa.Hsu@amd.com{ 22810905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 2296820SLisa.Hsu@amd.com string str; 23010905Sandreas.sandberg@arm.com if (!cp.find(section, name, str) || !parseParam(str, param)) { 2316820SLisa.Hsu@amd.com warn("optional parameter %s:%s not present\n", section, name); 2326820SLisa.Hsu@amd.com return false; 2336820SLisa.Hsu@amd.com } else { 2346820SLisa.Hsu@amd.com return true; 2356820SLisa.Hsu@amd.com } 2366820SLisa.Hsu@amd.com} 237217SN/A 238217SN/Atemplate <class T> 239217SN/Avoid 24010905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name, 24110905Sandreas.sandberg@arm.com const T *param, unsigned size) 242217SN/A{ 243217SN/A os << name << "="; 244217SN/A if (size > 0) 245217SN/A showParam(os, param[0]); 2466227Snate@binkert.org for (unsigned i = 1; i < size; ++i) { 247217SN/A os << " "; 248217SN/A showParam(os, param[i]); 249217SN/A } 250217SN/A os << "\n"; 251217SN/A} 252217SN/A 253217SN/A 254217SN/Atemplate <class T> 255217SN/Avoid 25610905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size) 257217SN/A{ 25810905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 2596225Snate@binkert.org string str; 26010905Sandreas.sandberg@arm.com if (!cp.find(section, name, str)) { 261217SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 262217SN/A } 263217SN/A 264217SN/A // code below stolen from VectorParam<T>::parse(). 265217SN/A // it would be nice to unify these somehow... 266217SN/A 267217SN/A vector<string> tokens; 268217SN/A 269217SN/A tokenize(tokens, str, ' '); 270217SN/A 271217SN/A // Need this if we were doing a vector 272217SN/A // value.resize(tokens.size()); 273217SN/A 274217SN/A if (tokens.size() != size) { 275217SN/A fatal("Array size mismatch on %s:%s'\n", section, name); 276217SN/A } 277217SN/A 2786227Snate@binkert.org for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 279217SN/A // need to parse into local variable to handle vector<bool>, 280217SN/A // for which operator[] returns a special reference class 281217SN/A // that's not the same as 'bool&', (since it's a packed 282217SN/A // vector) 28310905Sandreas.sandberg@arm.com T scalar_value; 284217SN/A if (!parseParam(tokens[i], scalar_value)) { 285217SN/A string err("could not parse \""); 286217SN/A 287217SN/A err += str; 288217SN/A err += "\""; 289217SN/A 290217SN/A fatal(err); 291217SN/A } 292217SN/A 293217SN/A // assign parsed value to vector 294217SN/A param[i] = scalar_value; 295217SN/A } 296217SN/A} 297217SN/A 2984841Ssaidi@eecs.umich.edutemplate <class T> 2994841Ssaidi@eecs.umich.eduvoid 30010905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, vector<T> ¶m) 3014841Ssaidi@eecs.umich.edu{ 30210905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 3036225Snate@binkert.org string str; 30410905Sandreas.sandberg@arm.com if (!cp.find(section, name, str)) { 3054841Ssaidi@eecs.umich.edu fatal("Can't unserialize '%s:%s'\n", section, name); 3064841Ssaidi@eecs.umich.edu } 3074841Ssaidi@eecs.umich.edu 3084841Ssaidi@eecs.umich.edu // code below stolen from VectorParam<T>::parse(). 3094841Ssaidi@eecs.umich.edu // it would be nice to unify these somehow... 3104841Ssaidi@eecs.umich.edu 3114841Ssaidi@eecs.umich.edu vector<string> tokens; 3124841Ssaidi@eecs.umich.edu 3134841Ssaidi@eecs.umich.edu tokenize(tokens, str, ' '); 3144841Ssaidi@eecs.umich.edu 3154841Ssaidi@eecs.umich.edu // Need this if we were doing a vector 3164841Ssaidi@eecs.umich.edu // value.resize(tokens.size()); 3174841Ssaidi@eecs.umich.edu 3184841Ssaidi@eecs.umich.edu param.resize(tokens.size()); 3194841Ssaidi@eecs.umich.edu 3206227Snate@binkert.org for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 3214841Ssaidi@eecs.umich.edu // need to parse into local variable to handle vector<bool>, 3224841Ssaidi@eecs.umich.edu // for which operator[] returns a special reference class 3234841Ssaidi@eecs.umich.edu // that's not the same as 'bool&', (since it's a packed 3244841Ssaidi@eecs.umich.edu // vector) 32510905Sandreas.sandberg@arm.com T scalar_value; 3264841Ssaidi@eecs.umich.edu if (!parseParam(tokens[i], scalar_value)) { 3274841Ssaidi@eecs.umich.edu string err("could not parse \""); 3284841Ssaidi@eecs.umich.edu 3294841Ssaidi@eecs.umich.edu err += str; 3304841Ssaidi@eecs.umich.edu err += "\""; 3314841Ssaidi@eecs.umich.edu 3324841Ssaidi@eecs.umich.edu fatal(err); 3334841Ssaidi@eecs.umich.edu } 3344841Ssaidi@eecs.umich.edu 3354841Ssaidi@eecs.umich.edu // assign parsed value to vector 3364841Ssaidi@eecs.umich.edu param[i] = scalar_value; 3374841Ssaidi@eecs.umich.edu } 3384841Ssaidi@eecs.umich.edu} 3394841Ssaidi@eecs.umich.edu 3407948SAli.Saidi@ARM.comtemplate <class T> 3417948SAli.Saidi@ARM.comvoid 34210905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, list<T> ¶m) 3437948SAli.Saidi@ARM.com{ 34410905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 3457948SAli.Saidi@ARM.com string str; 34610905Sandreas.sandberg@arm.com if (!cp.find(section, name, str)) { 3477948SAli.Saidi@ARM.com fatal("Can't unserialize '%s:%s'\n", section, name); 3487948SAli.Saidi@ARM.com } 3497948SAli.Saidi@ARM.com param.clear(); 3507948SAli.Saidi@ARM.com 3517948SAli.Saidi@ARM.com vector<string> tokens; 3527948SAli.Saidi@ARM.com tokenize(tokens, str, ' '); 3537948SAli.Saidi@ARM.com 3547948SAli.Saidi@ARM.com for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 35510905Sandreas.sandberg@arm.com T scalar_value; 3567948SAli.Saidi@ARM.com if (!parseParam(tokens[i], scalar_value)) { 3577948SAli.Saidi@ARM.com string err("could not parse \""); 3587948SAli.Saidi@ARM.com 3597948SAli.Saidi@ARM.com err += str; 3607948SAli.Saidi@ARM.com err += "\""; 3617948SAli.Saidi@ARM.com 3627948SAli.Saidi@ARM.com fatal(err); 3637948SAli.Saidi@ARM.com } 3647948SAli.Saidi@ARM.com 3657948SAli.Saidi@ARM.com // assign parsed value to vector 3667948SAli.Saidi@ARM.com param.push_back(scalar_value); 3677948SAli.Saidi@ARM.com } 3687948SAli.Saidi@ARM.com} 3697948SAli.Saidi@ARM.com 3707948SAli.Saidi@ARM.com 371237SN/Avoid 37210905Sandreas.sandberg@arm.comobjParamIn(CheckpointIn &cp, const string &name, SimObject * ¶m) 373237SN/A{ 37410905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 37510905Sandreas.sandberg@arm.com if (!cp.findObj(section, name, param)) { 376237SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 377237SN/A } 378237SN/A} 379237SN/A 380237SN/A 3815543Ssaidi@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type) \ 38210905Sandreas.sandberg@arm.com template void \ 38310905Sandreas.sandberg@arm.com paramOut(CheckpointOut &os, const string &name, type const ¶m); \ 38410905Sandreas.sandberg@arm.com template void \ 38510905Sandreas.sandberg@arm.com paramIn(CheckpointIn &cp, const string &name, type & param); \ 38610905Sandreas.sandberg@arm.com template bool \ 38710905Sandreas.sandberg@arm.com optParamIn(CheckpointIn &cp, const string &name, type & param); \ 38810905Sandreas.sandberg@arm.com template void \ 38910905Sandreas.sandberg@arm.com arrayParamOut(CheckpointOut &os, const string &name, \ 39010905Sandreas.sandberg@arm.com type const *param, unsigned size); \ 39110905Sandreas.sandberg@arm.com template void \ 39210905Sandreas.sandberg@arm.com arrayParamIn(CheckpointIn &cp, const string &name, \ 39310905Sandreas.sandberg@arm.com type *param, unsigned size); \ 39410905Sandreas.sandberg@arm.com template void \ 39510905Sandreas.sandberg@arm.com arrayParamOut(CheckpointOut &os, const string &name, \ 39610905Sandreas.sandberg@arm.com const vector<type> ¶m); \ 39710905Sandreas.sandberg@arm.com template void \ 39810905Sandreas.sandberg@arm.com arrayParamIn(CheckpointIn &cp, const string &name, \ 39910905Sandreas.sandberg@arm.com vector<type> ¶m); \ 40010905Sandreas.sandberg@arm.com template void \ 40110905Sandreas.sandberg@arm.com arrayParamOut(CheckpointOut &os, const string &name, \ 40210905Sandreas.sandberg@arm.com const list<type> ¶m); \ 40310905Sandreas.sandberg@arm.com template void \ 40410905Sandreas.sandberg@arm.com arrayParamIn(CheckpointIn &cp, const string &name, \ 40510905Sandreas.sandberg@arm.com list<type> ¶m); 406217SN/A 4077494Ssteve.reinhardt@amd.comINSTANTIATE_PARAM_TEMPLATES(char) 4081642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char) 4091642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char) 4101642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short) 4111642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short) 4121642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int) 4131642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int) 4141642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long) 4151642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long) 4161642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long) 4171642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long) 418219SN/AINSTANTIATE_PARAM_TEMPLATES(bool) 4195992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(float) 4205992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(double) 421217SN/AINSTANTIATE_PARAM_TEMPLATES(string) 42210907Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(Pixel) 423217SN/A 424217SN/A 425395SN/A///////////////////////////// 426395SN/A 427395SN/A/// Container for serializing global variables (not associated with 428395SN/A/// any serialized object). 429395SN/Aclass Globals : public Serializable 4302SN/A{ 431395SN/A public: 43210905Sandreas.sandberg@arm.com Globals() 43310905Sandreas.sandberg@arm.com : unserializedCurTick(0) {} 43410905Sandreas.sandberg@arm.com 43510905Sandreas.sandberg@arm.com void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 43610905Sandreas.sandberg@arm.com void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 43710905Sandreas.sandberg@arm.com 43810905Sandreas.sandberg@arm.com Tick unserializedCurTick; 439395SN/A}; 4402SN/A 441395SN/A/// The one and only instance of the Globals class. 442395SN/AGlobals globals; 4432SN/A 44410905Sandreas.sandberg@arm.comvoid 44510905Sandreas.sandberg@arm.comGlobals::serialize(CheckpointOut &cp) const 4462SN/A{ 44710905Sandreas.sandberg@arm.com paramOut(cp, "curTick", curTick()); 44810905Sandreas.sandberg@arm.com paramOut(cp, "numMainEventQueues", numMainEventQueues); 44910905Sandreas.sandberg@arm.com 4502SN/A} 4512SN/A 4522SN/Avoid 45310905Sandreas.sandberg@arm.comGlobals::unserialize(CheckpointIn &cp) 4542SN/A{ 45510905Sandreas.sandberg@arm.com paramIn(cp, "curTick", unserializedCurTick); 45610905Sandreas.sandberg@arm.com paramIn(cp, "numMainEventQueues", numMainEventQueues); 4572SN/A} 4582SN/A 4595739Snate@binkert.orgSerializable::Serializable() 4605739Snate@binkert.org{ 4615739Snate@binkert.org} 4625739Snate@binkert.org 4635739Snate@binkert.orgSerializable::~Serializable() 4645739Snate@binkert.org{ 4655739Snate@binkert.org} 4665739Snate@binkert.org 4675739Snate@binkert.orgvoid 46810905Sandreas.sandberg@arm.comSerializable::serializeSection(CheckpointOut &cp, const char *name) const 4695739Snate@binkert.org{ 47010905Sandreas.sandberg@arm.com Serializable::ScopedCheckpointSection sec(cp, name); 47110905Sandreas.sandberg@arm.com serialize(cp); 4725739Snate@binkert.org} 4735739Snate@binkert.org 4745739Snate@binkert.orgvoid 47510905Sandreas.sandberg@arm.comSerializable::serializeSectionOld(CheckpointOut &cp, const char *name) 4765739Snate@binkert.org{ 47710905Sandreas.sandberg@arm.com Serializable::ScopedCheckpointSection sec(cp, name); 47810905Sandreas.sandberg@arm.com serializeOld(cp); 47910905Sandreas.sandberg@arm.com} 48010905Sandreas.sandberg@arm.com 48110905Sandreas.sandberg@arm.comvoid 48210905Sandreas.sandberg@arm.comSerializable::unserializeSection(CheckpointIn &cp, const char *name) 48310905Sandreas.sandberg@arm.com{ 48410905Sandreas.sandberg@arm.com Serializable::ScopedCheckpointSection sec(cp, name); 48510905Sandreas.sandberg@arm.com unserialize(cp); 4865739Snate@binkert.org} 4875739Snate@binkert.org 4882SN/Avoid 4896225Snate@binkert.orgSerializable::serializeAll(const string &cpt_dir) 4902SN/A{ 49110905Sandreas.sandberg@arm.com string dir = CheckpointIn::setDir(cpt_dir); 492363SN/A if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) 493449SN/A fatal("couldn't mkdir %s\n", dir); 494363SN/A 49510905Sandreas.sandberg@arm.com string cpt_file = dir + CheckpointIn::baseFilename; 496395SN/A ofstream outstream(cpt_file.c_str()); 4972SN/A time_t t = time(NULL); 4985581Ssaidi@eecs.umich.edu if (!outstream.is_open()) 4995581Ssaidi@eecs.umich.edu fatal("Unable to open file %s for writing\n", cpt_file.c_str()); 5006818SLisa.Hsu@amd.com outstream << "## checkpoint generated: " << ctime(&t); 5012SN/A 50210905Sandreas.sandberg@arm.com globals.serializeSection(outstream, "Globals"); 50310905Sandreas.sandberg@arm.com for (uint32_t i = 0; i < numMainEventQueues; ++i) 50410905Sandreas.sandberg@arm.com mainEventQueue[i]->serializeSection(outstream, "MainEventQueue"); 50510905Sandreas.sandberg@arm.com 506395SN/A SimObject::serializeAll(outstream); 507395SN/A} 5082SN/A 5092797Sktlim@umich.eduvoid 51010905Sandreas.sandberg@arm.comSerializable::unserializeGlobals(CheckpointIn &cp) 511395SN/A{ 51210905Sandreas.sandberg@arm.com globals.unserializeSection(cp, "Globals"); 51310905Sandreas.sandberg@arm.com 51410905Sandreas.sandberg@arm.com for (uint32_t i = 0; i < numMainEventQueues; ++i) { 51510905Sandreas.sandberg@arm.com mainEventQueue[i]->setCurTick(globals.unserializedCurTick); 51610905Sandreas.sandberg@arm.com mainEventQueue[i]->unserializeSection(cp, "MainEventQueue"); 51710905Sandreas.sandberg@arm.com } 51810905Sandreas.sandberg@arm.com} 51910905Sandreas.sandberg@arm.com 52010905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::~ScopedCheckpointSection() 52110905Sandreas.sandberg@arm.com{ 52210905Sandreas.sandberg@arm.com assert(!path.empty()); 52310905Sandreas.sandberg@arm.com DPRINTF(Checkpoint, "Popping: %s\n", path.top()); 52410905Sandreas.sandberg@arm.com path.pop(); 52510905Sandreas.sandberg@arm.com} 52610905Sandreas.sandberg@arm.com 52710905Sandreas.sandberg@arm.comvoid 52810905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::pushName(const char *obj_name) 52910905Sandreas.sandberg@arm.com{ 53010905Sandreas.sandberg@arm.com if (path.empty()) { 53110905Sandreas.sandberg@arm.com path.push(obj_name); 53210905Sandreas.sandberg@arm.com } else { 53310905Sandreas.sandberg@arm.com path.push(csprintf("%s.%s", path.top(), obj_name)); 53410905Sandreas.sandberg@arm.com } 53510905Sandreas.sandberg@arm.com DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name); 53610905Sandreas.sandberg@arm.com} 53710905Sandreas.sandberg@arm.com 53810905Sandreas.sandberg@arm.comvoid 53910905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp) 54010905Sandreas.sandberg@arm.com{ 54110905Sandreas.sandberg@arm.com DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n", 54210905Sandreas.sandberg@arm.com Serializable::currentSection()); 54310905Sandreas.sandberg@arm.com cp << "\n[" << Serializable::currentSection() << "]\n"; 544395SN/A} 5452SN/A 5462SN/Avoid 5476225Snate@binkert.orgdebug_serialize(const string &cpt_dir) 5482SN/A{ 5492868Sktlim@umich.edu Serializable::serializeAll(cpt_dir); 5502SN/A} 5512SN/A 5522SN/A 5532SN/A//////////////////////////////////////////////////////////////////////// 5542SN/A// 555395SN/A// SerializableClass member definitions 5562SN/A// 5572SN/A//////////////////////////////////////////////////////////////////////// 5582SN/A 559395SN/A// Map of class names to SerializableBuilder creation functions. 5602SN/A// Need to make this a pointer so we can force initialization on the 561395SN/A// first reference; otherwise, some SerializableClass constructors 5622SN/A// may be invoked before the classMap constructor. 5636225Snate@binkert.orgmap<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0; 5642SN/A 565395SN/A// SerializableClass constructor: add mapping to classMap 566395SN/ASerializableClass::SerializableClass(const string &className, 5676225Snate@binkert.org CreateFunc createFunc) 5682SN/A{ 5692SN/A if (classMap == NULL) 5706225Snate@binkert.org classMap = new map<string, SerializableClass::CreateFunc>(); 5712SN/A 5722SN/A if ((*classMap)[className]) 5736225Snate@binkert.org fatal("Error: simulation object class %s redefined\n", className); 5742SN/A 5752SN/A // add className --> createFunc to class map 5762SN/A (*classMap)[className] = createFunc; 5772SN/A} 5782SN/A 5792SN/A// 5802SN/A// 581395SN/ASerializable * 58210905Sandreas.sandberg@arm.comSerializableClass::createObject(CheckpointIn &cp, const string §ion) 5832SN/A{ 584237SN/A string className; 5852SN/A 58610905Sandreas.sandberg@arm.com if (!cp.find(section, "type", className)) { 587395SN/A fatal("Serializable::create: no 'type' entry in section '%s'.\n", 588237SN/A section); 5892SN/A } 5902SN/A 591237SN/A CreateFunc createFunc = (*classMap)[className]; 592237SN/A 593237SN/A if (createFunc == NULL) { 594395SN/A fatal("Serializable::create: no create function for class '%s'.\n", 595237SN/A className); 5962SN/A } 5972SN/A 598395SN/A Serializable *object = createFunc(cp, section); 5992SN/A 6002SN/A assert(object != NULL); 6012SN/A 6022SN/A return object; 6032SN/A} 6042SN/A 60510905Sandreas.sandberg@arm.comconst std::string & 60610905Sandreas.sandberg@arm.comSerializable::currentSection() 60710905Sandreas.sandberg@arm.com{ 60810905Sandreas.sandberg@arm.com assert(!path.empty()); 60910905Sandreas.sandberg@arm.com 61010905Sandreas.sandberg@arm.com return path.top(); 61110905Sandreas.sandberg@arm.com} 612237SN/A 613395SN/ASerializable * 61410905Sandreas.sandberg@arm.comSerializable::create(CheckpointIn &cp, const string §ion) 615237SN/A{ 616395SN/A Serializable *object = SerializableClass::createObject(cp, section); 61710905Sandreas.sandberg@arm.com object->unserializeSection(cp, section); 618237SN/A return object; 619237SN/A} 620237SN/A 621237SN/A 62210905Sandreas.sandberg@arm.comconst char *CheckpointIn::baseFilename = "m5.cpt"; 6237491Ssteve.reinhardt@amd.com 62410905Sandreas.sandberg@arm.comstring CheckpointIn::currentDirectory; 6257491Ssteve.reinhardt@amd.com 6267491Ssteve.reinhardt@amd.comstring 62710905Sandreas.sandberg@arm.comCheckpointIn::setDir(const string &name) 6287491Ssteve.reinhardt@amd.com{ 6297823Ssteve.reinhardt@amd.com // use csprintf to insert curTick() into directory name if it 6307491Ssteve.reinhardt@amd.com // appears to have a format placeholder in it. 6317491Ssteve.reinhardt@amd.com currentDirectory = (name.find("%") != string::npos) ? 6327823Ssteve.reinhardt@amd.com csprintf(name, curTick()) : name; 6337491Ssteve.reinhardt@amd.com if (currentDirectory[currentDirectory.size() - 1] != '/') 6347491Ssteve.reinhardt@amd.com currentDirectory += "/"; 6357491Ssteve.reinhardt@amd.com return currentDirectory; 6367491Ssteve.reinhardt@amd.com} 6377491Ssteve.reinhardt@amd.com 6387491Ssteve.reinhardt@amd.comstring 63910905Sandreas.sandberg@arm.comCheckpointIn::dir() 6407491Ssteve.reinhardt@amd.com{ 6417491Ssteve.reinhardt@amd.com return currentDirectory; 6427491Ssteve.reinhardt@amd.com} 6437491Ssteve.reinhardt@amd.com 6447491Ssteve.reinhardt@amd.com 64510905Sandreas.sandberg@arm.comCheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver) 64610453SAndrew.Bardsley@arm.com : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir)) 647237SN/A{ 64810905Sandreas.sandberg@arm.com string filename = cptDir + "/" + CheckpointIn::baseFilename; 649237SN/A if (!db->load(filename)) { 650237SN/A fatal("Can't load checkpoint file '%s'\n", filename); 651237SN/A } 652237SN/A} 653237SN/A 65410905Sandreas.sandberg@arm.comCheckpointIn::~CheckpointIn() 6559086Sandreas.hansson@arm.com{ 6569086Sandreas.hansson@arm.com delete db; 6579086Sandreas.hansson@arm.com} 658237SN/A 659237SN/Abool 66010905Sandreas.sandberg@arm.comCheckpointIn::find(const string §ion, const string &entry, string &value) 661237SN/A{ 662237SN/A return db->find(section, entry, value); 663237SN/A} 664237SN/A 665237SN/A 666237SN/Abool 66710905Sandreas.sandberg@arm.comCheckpointIn::findObj(const string §ion, const string &entry, 6684000Ssaidi@eecs.umich.edu SimObject *&value) 669237SN/A{ 670237SN/A string path; 671237SN/A 672237SN/A if (!db->find(section, entry, path)) 673237SN/A return false; 674237SN/A 67510453SAndrew.Bardsley@arm.com value = objNameResolver.resolveSimObject(path); 6764000Ssaidi@eecs.umich.edu return true; 677237SN/A} 678304SN/A 679304SN/A 680304SN/Abool 68110905Sandreas.sandberg@arm.comCheckpointIn::sectionExists(const string §ion) 682304SN/A{ 683304SN/A return db->sectionExists(section); 684304SN/A} 685