serialize.cc revision 8737
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282760Sbinkertn@umich.edu * Authors: Nathan Binkert 292760Sbinkertn@umich.edu * Erik Hallnor 302665Ssaidi@eecs.umich.edu * Steve Reinhardt 312SN/A */ 322SN/A 338229Snate@binkert.org#include <sys/stat.h> 342SN/A#include <sys/time.h> 35363SN/A#include <sys/types.h> 362SN/A 378229Snate@binkert.org#include <cerrno> 382SN/A#include <fstream> 392SN/A#include <list> 402SN/A#include <string> 412SN/A#include <vector> 422SN/A 43363SN/A#include "base/inifile.hh" 4456SN/A#include "base/misc.hh" 451388SN/A#include "base/output.hh" 46217SN/A#include "base/str.hh" 47363SN/A#include "base/trace.hh" 4856SN/A#include "sim/eventq.hh" 4956SN/A#include "sim/serialize.hh" 5056SN/A#include "sim/sim_events.hh" 511638SN/A#include "sim/sim_exit.hh" 5256SN/A#include "sim/sim_object.hh" 532SN/A 542356SN/A// For stat reset hack 552356SN/A#include "sim/stat_control.hh" 562356SN/A 572SN/Ausing namespace std; 582SN/A 594000Ssaidi@eecs.umich.eduextern SimObject *resolveSimObject(const string &); 604000Ssaidi@eecs.umich.edu 614762Snate@binkert.org// 624762Snate@binkert.org// The base implementations use to_number for parsing and '<<' for 634762Snate@binkert.org// displaying, suitable for integer types. 644762Snate@binkert.org// 654762Snate@binkert.orgtemplate <class T> 664762Snate@binkert.orgbool 674762Snate@binkert.orgparseParam(const string &s, T &value) 684762Snate@binkert.org{ 694762Snate@binkert.org return to_number(s, value); 704762Snate@binkert.org} 714762Snate@binkert.org 724762Snate@binkert.orgtemplate <class T> 734762Snate@binkert.orgvoid 744762Snate@binkert.orgshowParam(ostream &os, const T &value) 754762Snate@binkert.org{ 764762Snate@binkert.org os << value; 774762Snate@binkert.org} 784762Snate@binkert.org 794762Snate@binkert.org// 804762Snate@binkert.org// Template specializations: 814762Snate@binkert.org// - char (8-bit integer) 824762Snate@binkert.org// - floating-point types 834762Snate@binkert.org// - bool 844762Snate@binkert.org// - string 854762Snate@binkert.org// 864762Snate@binkert.org 874762Snate@binkert.org// Treat 8-bit ints (chars) as ints on output, not as chars 884762Snate@binkert.orgtemplate <> 894762Snate@binkert.orgvoid 907494Ssteve.reinhardt@amd.comshowParam(ostream &os, const char &value) 917494Ssteve.reinhardt@amd.com{ 927494Ssteve.reinhardt@amd.com os << (int)value; 937494Ssteve.reinhardt@amd.com} 947494Ssteve.reinhardt@amd.com 957494Ssteve.reinhardt@amd.com 967494Ssteve.reinhardt@amd.comtemplate <> 977494Ssteve.reinhardt@amd.comvoid 987490Ssteve.reinhardt@amd.comshowParam(ostream &os, const signed char &value) 994762Snate@binkert.org{ 1004762Snate@binkert.org os << (int)value; 1014762Snate@binkert.org} 1024762Snate@binkert.org 1034762Snate@binkert.org 1044762Snate@binkert.orgtemplate <> 1054762Snate@binkert.orgvoid 1064762Snate@binkert.orgshowParam(ostream &os, const unsigned char &value) 1074762Snate@binkert.org{ 1084762Snate@binkert.org os << (unsigned int)value; 1094762Snate@binkert.org} 1104762Snate@binkert.org 1114762Snate@binkert.org 1124762Snate@binkert.org// Use sscanf() for FP types as to_number() only handles integers 1134762Snate@binkert.orgtemplate <> 1144762Snate@binkert.orgbool 1154762Snate@binkert.orgparseParam(const string &s, float &value) 1164762Snate@binkert.org{ 1174762Snate@binkert.org return (sscanf(s.c_str(), "%f", &value) == 1); 1184762Snate@binkert.org} 1194762Snate@binkert.org 1204762Snate@binkert.orgtemplate <> 1214762Snate@binkert.orgbool 1224762Snate@binkert.orgparseParam(const string &s, double &value) 1234762Snate@binkert.org{ 1244762Snate@binkert.org return (sscanf(s.c_str(), "%lf", &value) == 1); 1254762Snate@binkert.org} 1264762Snate@binkert.org 1274762Snate@binkert.orgtemplate <> 1284762Snate@binkert.orgbool 1294762Snate@binkert.orgparseParam(const string &s, bool &value) 1304762Snate@binkert.org{ 1314762Snate@binkert.org const string &ls = to_lower(s); 1324762Snate@binkert.org 1334762Snate@binkert.org if (ls == "true") { 1344762Snate@binkert.org value = true; 1354762Snate@binkert.org return true; 1364762Snate@binkert.org } 1374762Snate@binkert.org 1384762Snate@binkert.org if (ls == "false") { 1394762Snate@binkert.org value = false; 1404762Snate@binkert.org return true; 1414762Snate@binkert.org } 1424762Snate@binkert.org 1434762Snate@binkert.org return false; 1444762Snate@binkert.org} 1454762Snate@binkert.org 1464762Snate@binkert.org// Display bools as strings 1474762Snate@binkert.orgtemplate <> 1484762Snate@binkert.orgvoid 1494762Snate@binkert.orgshowParam(ostream &os, const bool &value) 1504762Snate@binkert.org{ 1514762Snate@binkert.org os << (value ? "true" : "false"); 1524762Snate@binkert.org} 1534762Snate@binkert.org 1544762Snate@binkert.org 1554762Snate@binkert.org// String requires no processing to speak of 1564762Snate@binkert.orgtemplate <> 1574762Snate@binkert.orgbool 1584762Snate@binkert.orgparseParam(const string &s, string &value) 1594762Snate@binkert.org{ 1604762Snate@binkert.org value = s; 1614762Snate@binkert.org return true; 1624762Snate@binkert.org} 1634762Snate@binkert.org 1642287SN/Aint Serializable::ckptMaxCount = 0; 1652287SN/Aint Serializable::ckptCount = 0; 1662287SN/Aint Serializable::ckptPrevCount = -1; 1671637SN/A 1682SN/Avoid 169395SN/ASerializable::nameOut(ostream &os) 1702SN/A{ 171217SN/A os << "\n[" << name() << "]\n"; 1722SN/A} 1732SN/A 1742SN/Avoid 175395SN/ASerializable::nameOut(ostream &os, const string &_name) 1762SN/A{ 177217SN/A os << "\n[" << _name << "]\n"; 1782SN/A} 1792SN/A 180217SN/Atemplate <class T> 1812SN/Avoid 1826225Snate@binkert.orgparamOut(ostream &os, const string &name, const T ¶m) 1832SN/A{ 184217SN/A os << name << "="; 185217SN/A showParam(os, param); 186217SN/A os << "\n"; 1872SN/A} 1882SN/A 1894841Ssaidi@eecs.umich.edutemplate <class T> 1904841Ssaidi@eecs.umich.eduvoid 1916225Snate@binkert.orgarrayParamOut(ostream &os, const string &name, const vector<T> ¶m) 1924841Ssaidi@eecs.umich.edu{ 1936227Snate@binkert.org typename vector<T>::size_type size = param.size(); 1944841Ssaidi@eecs.umich.edu os << name << "="; 1954841Ssaidi@eecs.umich.edu if (size > 0) 1964841Ssaidi@eecs.umich.edu showParam(os, param[0]); 1976227Snate@binkert.org for (typename vector<T>::size_type i = 1; i < size; ++i) { 1984841Ssaidi@eecs.umich.edu os << " "; 1994841Ssaidi@eecs.umich.edu showParam(os, param[i]); 2004841Ssaidi@eecs.umich.edu } 2014841Ssaidi@eecs.umich.edu os << "\n"; 2024841Ssaidi@eecs.umich.edu} 2034841Ssaidi@eecs.umich.edu 2047948SAli.Saidi@ARM.comtemplate <class T> 2057948SAli.Saidi@ARM.comvoid 2067948SAli.Saidi@ARM.comarrayParamOut(ostream &os, const string &name, const list<T> ¶m) 2077948SAli.Saidi@ARM.com{ 2087948SAli.Saidi@ARM.com typename list<T>::const_iterator it = param.begin(); 2097948SAli.Saidi@ARM.com 2107948SAli.Saidi@ARM.com os << name << "="; 2117948SAli.Saidi@ARM.com if (param.size() > 0) 2127948SAli.Saidi@ARM.com showParam(os, *it); 2137948SAli.Saidi@ARM.com it++; 2147948SAli.Saidi@ARM.com while (it != param.end()) { 2157948SAli.Saidi@ARM.com os << " "; 2167948SAli.Saidi@ARM.com showParam(os, *it); 2177948SAli.Saidi@ARM.com it++; 2187948SAli.Saidi@ARM.com } 2197948SAli.Saidi@ARM.com os << "\n"; 2207948SAli.Saidi@ARM.com} 221217SN/A 222217SN/Atemplate <class T> 223217SN/Avoid 2246225Snate@binkert.orgparamIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) 2252SN/A{ 2266225Snate@binkert.org string str; 227237SN/A if (!cp->find(section, name, str) || !parseParam(str, param)) { 228217SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 229217SN/A } 2302SN/A} 2312SN/A 2326820SLisa.Hsu@amd.comtemplate <class T> 2336820SLisa.Hsu@amd.combool 2346820SLisa.Hsu@amd.comoptParamIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) 2356820SLisa.Hsu@amd.com{ 2366820SLisa.Hsu@amd.com string str; 2376820SLisa.Hsu@amd.com if (!cp->find(section, name, str) || !parseParam(str, param)) { 2386820SLisa.Hsu@amd.com warn("optional parameter %s:%s not present\n", section, name); 2396820SLisa.Hsu@amd.com return false; 2406820SLisa.Hsu@amd.com } else { 2416820SLisa.Hsu@amd.com return true; 2426820SLisa.Hsu@amd.com } 2436820SLisa.Hsu@amd.com} 244217SN/A 245217SN/Atemplate <class T> 246217SN/Avoid 2476227Snate@binkert.orgarrayParamOut(ostream &os, const string &name, const T *param, unsigned size) 248217SN/A{ 249217SN/A os << name << "="; 250217SN/A if (size > 0) 251217SN/A showParam(os, param[0]); 2526227Snate@binkert.org for (unsigned i = 1; i < size; ++i) { 253217SN/A os << " "; 254217SN/A showParam(os, param[i]); 255217SN/A } 256217SN/A os << "\n"; 257217SN/A} 258217SN/A 259217SN/A 260217SN/Atemplate <class T> 261217SN/Avoid 2626225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string §ion, const string &name, 2636227Snate@binkert.org T *param, unsigned size) 264217SN/A{ 2656225Snate@binkert.org string str; 266237SN/A if (!cp->find(section, name, str)) { 267217SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 268217SN/A } 269217SN/A 270217SN/A // code below stolen from VectorParam<T>::parse(). 271217SN/A // it would be nice to unify these somehow... 272217SN/A 273217SN/A vector<string> tokens; 274217SN/A 275217SN/A tokenize(tokens, str, ' '); 276217SN/A 277217SN/A // Need this if we were doing a vector 278217SN/A // value.resize(tokens.size()); 279217SN/A 280217SN/A if (tokens.size() != size) { 281217SN/A fatal("Array size mismatch on %s:%s'\n", section, name); 282217SN/A } 283217SN/A 2846227Snate@binkert.org for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 285217SN/A // need to parse into local variable to handle vector<bool>, 286217SN/A // for which operator[] returns a special reference class 287217SN/A // that's not the same as 'bool&', (since it's a packed 288217SN/A // vector) 2897576SAli.Saidi@ARM.com T scalar_value = 0; 290217SN/A if (!parseParam(tokens[i], scalar_value)) { 291217SN/A string err("could not parse \""); 292217SN/A 293217SN/A err += str; 294217SN/A err += "\""; 295217SN/A 296217SN/A fatal(err); 297217SN/A } 298217SN/A 299217SN/A // assign parsed value to vector 300217SN/A param[i] = scalar_value; 301217SN/A } 302217SN/A} 303217SN/A 3044841Ssaidi@eecs.umich.edutemplate <class T> 3054841Ssaidi@eecs.umich.eduvoid 3066225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string §ion, 3076225Snate@binkert.org const string &name, vector<T> ¶m) 3084841Ssaidi@eecs.umich.edu{ 3096225Snate@binkert.org string str; 3104841Ssaidi@eecs.umich.edu if (!cp->find(section, name, str)) { 3114841Ssaidi@eecs.umich.edu fatal("Can't unserialize '%s:%s'\n", section, name); 3124841Ssaidi@eecs.umich.edu } 3134841Ssaidi@eecs.umich.edu 3144841Ssaidi@eecs.umich.edu // code below stolen from VectorParam<T>::parse(). 3154841Ssaidi@eecs.umich.edu // it would be nice to unify these somehow... 3164841Ssaidi@eecs.umich.edu 3174841Ssaidi@eecs.umich.edu vector<string> tokens; 3184841Ssaidi@eecs.umich.edu 3194841Ssaidi@eecs.umich.edu tokenize(tokens, str, ' '); 3204841Ssaidi@eecs.umich.edu 3214841Ssaidi@eecs.umich.edu // Need this if we were doing a vector 3224841Ssaidi@eecs.umich.edu // value.resize(tokens.size()); 3234841Ssaidi@eecs.umich.edu 3244841Ssaidi@eecs.umich.edu param.resize(tokens.size()); 3254841Ssaidi@eecs.umich.edu 3266227Snate@binkert.org for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 3274841Ssaidi@eecs.umich.edu // need to parse into local variable to handle vector<bool>, 3284841Ssaidi@eecs.umich.edu // for which operator[] returns a special reference class 3294841Ssaidi@eecs.umich.edu // that's not the same as 'bool&', (since it's a packed 3304841Ssaidi@eecs.umich.edu // vector) 3317576SAli.Saidi@ARM.com T scalar_value = 0; 3324841Ssaidi@eecs.umich.edu if (!parseParam(tokens[i], scalar_value)) { 3334841Ssaidi@eecs.umich.edu string err("could not parse \""); 3344841Ssaidi@eecs.umich.edu 3354841Ssaidi@eecs.umich.edu err += str; 3364841Ssaidi@eecs.umich.edu err += "\""; 3374841Ssaidi@eecs.umich.edu 3384841Ssaidi@eecs.umich.edu fatal(err); 3394841Ssaidi@eecs.umich.edu } 3404841Ssaidi@eecs.umich.edu 3414841Ssaidi@eecs.umich.edu // assign parsed value to vector 3424841Ssaidi@eecs.umich.edu param[i] = scalar_value; 3434841Ssaidi@eecs.umich.edu } 3444841Ssaidi@eecs.umich.edu} 3454841Ssaidi@eecs.umich.edu 3467948SAli.Saidi@ARM.comtemplate <class T> 3477948SAli.Saidi@ARM.comvoid 3487948SAli.Saidi@ARM.comarrayParamIn(Checkpoint *cp, const string §ion, 3497948SAli.Saidi@ARM.com const string &name, list<T> ¶m) 3507948SAli.Saidi@ARM.com{ 3517948SAli.Saidi@ARM.com string str; 3527948SAli.Saidi@ARM.com if (!cp->find(section, name, str)) { 3537948SAli.Saidi@ARM.com fatal("Can't unserialize '%s:%s'\n", section, name); 3547948SAli.Saidi@ARM.com } 3557948SAli.Saidi@ARM.com param.clear(); 3567948SAli.Saidi@ARM.com 3577948SAli.Saidi@ARM.com vector<string> tokens; 3587948SAli.Saidi@ARM.com tokenize(tokens, str, ' '); 3597948SAli.Saidi@ARM.com 3607948SAli.Saidi@ARM.com for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 3617948SAli.Saidi@ARM.com T scalar_value = 0; 3627948SAli.Saidi@ARM.com if (!parseParam(tokens[i], scalar_value)) { 3637948SAli.Saidi@ARM.com string err("could not parse \""); 3647948SAli.Saidi@ARM.com 3657948SAli.Saidi@ARM.com err += str; 3667948SAli.Saidi@ARM.com err += "\""; 3677948SAli.Saidi@ARM.com 3687948SAli.Saidi@ARM.com fatal(err); 3697948SAli.Saidi@ARM.com } 3707948SAli.Saidi@ARM.com 3717948SAli.Saidi@ARM.com // assign parsed value to vector 3727948SAli.Saidi@ARM.com param.push_back(scalar_value); 3737948SAli.Saidi@ARM.com } 3747948SAli.Saidi@ARM.com} 3757948SAli.Saidi@ARM.com 3767948SAli.Saidi@ARM.com 377237SN/Avoid 3786225Snate@binkert.orgobjParamIn(Checkpoint *cp, const string §ion, 3796225Snate@binkert.org const string &name, SimObject * ¶m) 380237SN/A{ 381237SN/A if (!cp->findObj(section, name, param)) { 382237SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 383237SN/A } 384237SN/A} 385237SN/A 386237SN/A 3875543Ssaidi@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type) \ 3885543Ssaidi@eecs.umich.edutemplate void \ 3896225Snate@binkert.orgparamOut(ostream &os, const string &name, type const ¶m); \ 3905543Ssaidi@eecs.umich.edutemplate void \ 3916225Snate@binkert.orgparamIn(Checkpoint *cp, const string §ion, \ 3926225Snate@binkert.org const string &name, type & param); \ 3936820SLisa.Hsu@amd.comtemplate bool \ 3946820SLisa.Hsu@amd.comoptParamIn(Checkpoint *cp, const string §ion, \ 3956820SLisa.Hsu@amd.com const string &name, type & param); \ 3965543Ssaidi@eecs.umich.edutemplate void \ 3976225Snate@binkert.orgarrayParamOut(ostream &os, const string &name, \ 3986227Snate@binkert.org type const *param, unsigned size); \ 3995543Ssaidi@eecs.umich.edutemplate void \ 4006225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string §ion, \ 4016227Snate@binkert.org const string &name, type *param, unsigned size); \ 4025543Ssaidi@eecs.umich.edutemplate void \ 4036225Snate@binkert.orgarrayParamOut(ostream &os, const string &name, \ 4046225Snate@binkert.org const vector<type> ¶m); \ 4055543Ssaidi@eecs.umich.edutemplate void \ 4066225Snate@binkert.orgarrayParamIn(Checkpoint *cp, const string §ion, \ 4077948SAli.Saidi@ARM.com const string &name, vector<type> ¶m); \ 4087948SAli.Saidi@ARM.comtemplate void \ 4097948SAli.Saidi@ARM.comarrayParamOut(ostream &os, const string &name, \ 4107948SAli.Saidi@ARM.com const list<type> ¶m); \ 4117948SAli.Saidi@ARM.comtemplate void \ 4127948SAli.Saidi@ARM.comarrayParamIn(Checkpoint *cp, const string §ion, \ 4137948SAli.Saidi@ARM.com const string &name, list<type> ¶m); 414217SN/A 4157494Ssteve.reinhardt@amd.comINSTANTIATE_PARAM_TEMPLATES(char) 4161642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char) 4171642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char) 4181642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short) 4191642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short) 4201642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int) 4211642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int) 4221642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long) 4231642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long) 4241642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long) 4251642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long) 426219SN/AINSTANTIATE_PARAM_TEMPLATES(bool) 4275992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(float) 4285992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(double) 429217SN/AINSTANTIATE_PARAM_TEMPLATES(string) 430217SN/A 431217SN/A 432395SN/A///////////////////////////// 433395SN/A 434395SN/A/// Container for serializing global variables (not associated with 435395SN/A/// any serialized object). 436395SN/Aclass Globals : public Serializable 4372SN/A{ 438395SN/A public: 439512SN/A const string name() const; 440510SN/A void serialize(ostream &os); 4418737Skoansin.tan@gmail.com void unserialize(Checkpoint *cp, const std::string §ion); 442395SN/A}; 4432SN/A 444395SN/A/// The one and only instance of the Globals class. 445395SN/AGlobals globals; 4462SN/A 447512SN/Aconst string 448395SN/AGlobals::name() const 4492SN/A{ 450395SN/A return "Globals"; 4512SN/A} 4522SN/A 4532SN/Avoid 454510SN/AGlobals::serialize(ostream &os) 4552SN/A{ 456395SN/A nameOut(os); 4577864Ssteve.reinhardt@amd.com paramOut(os, "curTick", curTick()); 458395SN/A 459395SN/A nameOut(os, "MainEventQueue"); 460395SN/A mainEventQueue.serialize(os); 4612SN/A} 4622SN/A 4632SN/Avoid 4648737Skoansin.tan@gmail.comGlobals::unserialize(Checkpoint *cp, const std::string §ion) 4652SN/A{ 4667823Ssteve.reinhardt@amd.com Tick tick; 4677823Ssteve.reinhardt@amd.com paramIn(cp, section, "curTick", tick); 4687823Ssteve.reinhardt@amd.com curTick(tick); 4692SN/A 470395SN/A mainEventQueue.unserialize(cp, "MainEventQueue"); 4712SN/A} 4722SN/A 4735739Snate@binkert.orgSerializable::Serializable() 4745739Snate@binkert.org{ 4755739Snate@binkert.org} 4765739Snate@binkert.org 4775739Snate@binkert.orgSerializable::~Serializable() 4785739Snate@binkert.org{ 4795739Snate@binkert.org} 4805739Snate@binkert.org 4815739Snate@binkert.orgvoid 4826225Snate@binkert.orgSerializable::serialize(ostream &os) 4835739Snate@binkert.org{ 4845739Snate@binkert.org} 4855739Snate@binkert.org 4865739Snate@binkert.orgvoid 4876225Snate@binkert.orgSerializable::unserialize(Checkpoint *cp, const string §ion) 4885739Snate@binkert.org{ 4895739Snate@binkert.org} 4905739Snate@binkert.org 4912SN/Avoid 4926225Snate@binkert.orgSerializable::serializeAll(const string &cpt_dir) 4932SN/A{ 4947491Ssteve.reinhardt@amd.com string dir = Checkpoint::setDir(cpt_dir); 495363SN/A if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) 496449SN/A fatal("couldn't mkdir %s\n", dir); 497363SN/A 498449SN/A string cpt_file = dir + Checkpoint::baseFilename; 499395SN/A ofstream outstream(cpt_file.c_str()); 5002SN/A time_t t = time(NULL); 5015581Ssaidi@eecs.umich.edu if (!outstream.is_open()) 5025581Ssaidi@eecs.umich.edu fatal("Unable to open file %s for writing\n", cpt_file.c_str()); 5036818SLisa.Hsu@amd.com outstream << "## checkpoint generated: " << ctime(&t); 5042SN/A 505395SN/A globals.serialize(outstream); 506395SN/A SimObject::serializeAll(outstream); 507395SN/A} 5082SN/A 5092797Sktlim@umich.eduvoid 510395SN/ASerializable::unserializeGlobals(Checkpoint *cp) 511395SN/A{ 5128737Skoansin.tan@gmail.com globals.unserialize(cp, globals.name()); 513395SN/A} 5142SN/A 5152SN/Avoid 5166225Snate@binkert.orgdebug_serialize(const string &cpt_dir) 5172SN/A{ 5182868Sktlim@umich.edu Serializable::serializeAll(cpt_dir); 5192SN/A} 5202SN/A 5212SN/A 5222SN/A//////////////////////////////////////////////////////////////////////// 5232SN/A// 524395SN/A// SerializableClass member definitions 5252SN/A// 5262SN/A//////////////////////////////////////////////////////////////////////// 5272SN/A 528395SN/A// Map of class names to SerializableBuilder creation functions. 5292SN/A// Need to make this a pointer so we can force initialization on the 530395SN/A// first reference; otherwise, some SerializableClass constructors 5312SN/A// may be invoked before the classMap constructor. 5326225Snate@binkert.orgmap<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0; 5332SN/A 534395SN/A// SerializableClass constructor: add mapping to classMap 535395SN/ASerializableClass::SerializableClass(const string &className, 5366225Snate@binkert.org CreateFunc createFunc) 5372SN/A{ 5382SN/A if (classMap == NULL) 5396225Snate@binkert.org classMap = new map<string, SerializableClass::CreateFunc>(); 5402SN/A 5412SN/A if ((*classMap)[className]) 5426225Snate@binkert.org fatal("Error: simulation object class %s redefined\n", className); 5432SN/A 5442SN/A // add className --> createFunc to class map 5452SN/A (*classMap)[className] = createFunc; 5462SN/A} 5472SN/A 5482SN/A// 5492SN/A// 550395SN/ASerializable * 5516225Snate@binkert.orgSerializableClass::createObject(Checkpoint *cp, const string §ion) 5522SN/A{ 553237SN/A string className; 5542SN/A 555237SN/A if (!cp->find(section, "type", className)) { 556395SN/A fatal("Serializable::create: no 'type' entry in section '%s'.\n", 557237SN/A section); 5582SN/A } 5592SN/A 560237SN/A CreateFunc createFunc = (*classMap)[className]; 561237SN/A 562237SN/A if (createFunc == NULL) { 563395SN/A fatal("Serializable::create: no create function for class '%s'.\n", 564237SN/A className); 5652SN/A } 5662SN/A 567395SN/A Serializable *object = createFunc(cp, section); 5682SN/A 5692SN/A assert(object != NULL); 5702SN/A 5712SN/A return object; 5722SN/A} 5732SN/A 574237SN/A 575395SN/ASerializable * 5766225Snate@binkert.orgSerializable::create(Checkpoint *cp, const string §ion) 577237SN/A{ 578395SN/A Serializable *object = SerializableClass::createObject(cp, section); 579237SN/A object->unserialize(cp, section); 580237SN/A return object; 581237SN/A} 582237SN/A 583237SN/A 5847491Ssteve.reinhardt@amd.comconst char *Checkpoint::baseFilename = "m5.cpt"; 5857491Ssteve.reinhardt@amd.com 5867491Ssteve.reinhardt@amd.comstring Checkpoint::currentDirectory; 5877491Ssteve.reinhardt@amd.com 5887491Ssteve.reinhardt@amd.comstring 5897491Ssteve.reinhardt@amd.comCheckpoint::setDir(const string &name) 5907491Ssteve.reinhardt@amd.com{ 5917823Ssteve.reinhardt@amd.com // use csprintf to insert curTick() into directory name if it 5927491Ssteve.reinhardt@amd.com // appears to have a format placeholder in it. 5937491Ssteve.reinhardt@amd.com currentDirectory = (name.find("%") != string::npos) ? 5947823Ssteve.reinhardt@amd.com csprintf(name, curTick()) : name; 5957491Ssteve.reinhardt@amd.com if (currentDirectory[currentDirectory.size() - 1] != '/') 5967491Ssteve.reinhardt@amd.com currentDirectory += "/"; 5977491Ssteve.reinhardt@amd.com return currentDirectory; 5987491Ssteve.reinhardt@amd.com} 5997491Ssteve.reinhardt@amd.com 6007491Ssteve.reinhardt@amd.comstring 6017491Ssteve.reinhardt@amd.comCheckpoint::dir() 6027491Ssteve.reinhardt@amd.com{ 6037491Ssteve.reinhardt@amd.com return currentDirectory; 6047491Ssteve.reinhardt@amd.com} 6057491Ssteve.reinhardt@amd.com 6067491Ssteve.reinhardt@amd.com 6077491Ssteve.reinhardt@amd.comCheckpoint::Checkpoint(const string &cpt_dir) 6087532Ssteve.reinhardt@amd.com : db(new IniFile), cptDir(setDir(cpt_dir)) 609237SN/A{ 6107532Ssteve.reinhardt@amd.com string filename = cptDir + "/" + Checkpoint::baseFilename; 611237SN/A if (!db->load(filename)) { 612237SN/A fatal("Can't load checkpoint file '%s'\n", filename); 613237SN/A } 614237SN/A} 615237SN/A 616237SN/A 617237SN/Abool 6186225Snate@binkert.orgCheckpoint::find(const string §ion, const string &entry, string &value) 619237SN/A{ 620237SN/A return db->find(section, entry, value); 621237SN/A} 622237SN/A 623237SN/A 624237SN/Abool 6256225Snate@binkert.orgCheckpoint::findObj(const string §ion, const string &entry, 6264000Ssaidi@eecs.umich.edu SimObject *&value) 627237SN/A{ 628237SN/A string path; 629237SN/A 630237SN/A if (!db->find(section, entry, path)) 631237SN/A return false; 632237SN/A 6334000Ssaidi@eecs.umich.edu value = resolveSimObject(path); 6344000Ssaidi@eecs.umich.edu return true; 635237SN/A} 636304SN/A 637304SN/A 638304SN/Abool 6396225Snate@binkert.orgCheckpoint::sectionExists(const string §ion) 640304SN/A{ 641304SN/A return db->sectionExists(section); 642304SN/A} 643