serialize.cc revision 7823
15831Sgblack@eecs.umich.edu/* 25831Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 35831Sgblack@eecs.umich.edu * All rights reserved. 45831Sgblack@eecs.umich.edu * 55831Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 65831Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 75831Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 85831Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 95831Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 105831Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 115831Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 125831Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 135831Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 145831Sgblack@eecs.umich.edu * this software without specific prior written permission. 155831Sgblack@eecs.umich.edu * 165831Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175831Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185831Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195831Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205831Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215831Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225831Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235831Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245831Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255831Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265831Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275831Sgblack@eecs.umich.edu * 285831Sgblack@eecs.umich.edu * Authors: Nathan Binkert 295831Sgblack@eecs.umich.edu * Erik Hallnor 305831Sgblack@eecs.umich.edu * Steve Reinhardt 315831Sgblack@eecs.umich.edu */ 325831Sgblack@eecs.umich.edu 335831Sgblack@eecs.umich.edu#include <sys/time.h> 348229Snate@binkert.org#include <sys/types.h> 358229Snate@binkert.org#include <sys/stat.h> 368229Snate@binkert.org#include <errno.h> 375831Sgblack@eecs.umich.edu 385831Sgblack@eecs.umich.edu#include <fstream> 395831Sgblack@eecs.umich.edu#include <list> 405831Sgblack@eecs.umich.edu#include <string> 415831Sgblack@eecs.umich.edu#include <vector> 425831Sgblack@eecs.umich.edu 435831Sgblack@eecs.umich.edu#include "base/inifile.hh" 445831Sgblack@eecs.umich.edu#include "base/misc.hh" 455832Sgblack@eecs.umich.edu#include "base/output.hh" 465832Sgblack@eecs.umich.edu#include "base/str.hh" 475832Sgblack@eecs.umich.edu#include "base/trace.hh" 485832Sgblack@eecs.umich.edu#include "sim/eventq.hh" 495832Sgblack@eecs.umich.edu#include "sim/serialize.hh" 505832Sgblack@eecs.umich.edu#include "sim/sim_events.hh" 515832Sgblack@eecs.umich.edu#include "sim/sim_exit.hh" 525832Sgblack@eecs.umich.edu#include "sim/sim_object.hh" 535832Sgblack@eecs.umich.edu 545832Sgblack@eecs.umich.edu// For stat reset hack 555832Sgblack@eecs.umich.edu#include "sim/stat_control.hh" 565832Sgblack@eecs.umich.edu 575832Sgblack@eecs.umich.eduusing namespace std; 585832Sgblack@eecs.umich.edu 595832Sgblack@eecs.umich.eduextern SimObject *resolveSimObject(const string &); 605832Sgblack@eecs.umich.edu 615832Sgblack@eecs.umich.edu// 625832Sgblack@eecs.umich.edu// The base implementations use to_number for parsing and '<<' for 635832Sgblack@eecs.umich.edu// displaying, suitable for integer types. 645832Sgblack@eecs.umich.edu// 655832Sgblack@eecs.umich.edutemplate <class T> 665832Sgblack@eecs.umich.edubool 675832Sgblack@eecs.umich.eduparseParam(const string &s, T &value) 685832Sgblack@eecs.umich.edu{ 695832Sgblack@eecs.umich.edu return to_number(s, value); 705832Sgblack@eecs.umich.edu} 715832Sgblack@eecs.umich.edu 725832Sgblack@eecs.umich.edutemplate <class T> 735832Sgblack@eecs.umich.eduvoid 745832Sgblack@eecs.umich.edushowParam(ostream &os, const T &value) 755832Sgblack@eecs.umich.edu{ 765832Sgblack@eecs.umich.edu os << value; 775832Sgblack@eecs.umich.edu} 785832Sgblack@eecs.umich.edu 795832Sgblack@eecs.umich.edu// 805832Sgblack@eecs.umich.edu// Template specializations: 815832Sgblack@eecs.umich.edu// - char (8-bit integer) 825832Sgblack@eecs.umich.edu// - floating-point types 835832Sgblack@eecs.umich.edu// - bool 845832Sgblack@eecs.umich.edu// - string 855832Sgblack@eecs.umich.edu// 865832Sgblack@eecs.umich.edu 875832Sgblack@eecs.umich.edu// Treat 8-bit ints (chars) as ints on output, not as chars 885832Sgblack@eecs.umich.edutemplate <> 895832Sgblack@eecs.umich.eduvoid 905832Sgblack@eecs.umich.edushowParam(ostream &os, const char &value) 915832Sgblack@eecs.umich.edu{ 925832Sgblack@eecs.umich.edu os << (int)value; 935832Sgblack@eecs.umich.edu} 945832Sgblack@eecs.umich.edu 955832Sgblack@eecs.umich.edu 965832Sgblack@eecs.umich.edutemplate <> 975832Sgblack@eecs.umich.eduvoid 985832Sgblack@eecs.umich.edushowParam(ostream &os, const signed char &value) 995832Sgblack@eecs.umich.edu{ 1005832Sgblack@eecs.umich.edu os << (int)value; 1015832Sgblack@eecs.umich.edu} 1025832Sgblack@eecs.umich.edu 1035832Sgblack@eecs.umich.edu 1045832Sgblack@eecs.umich.edutemplate <> 1055832Sgblack@eecs.umich.eduvoid 1065832Sgblack@eecs.umich.edushowParam(ostream &os, const unsigned char &value) 1075832Sgblack@eecs.umich.edu{ 1085832Sgblack@eecs.umich.edu os << (unsigned int)value; 1095832Sgblack@eecs.umich.edu} 1105832Sgblack@eecs.umich.edu 1115832Sgblack@eecs.umich.edu 1125832Sgblack@eecs.umich.edu// Use sscanf() for FP types as to_number() only handles integers 1135832Sgblack@eecs.umich.edutemplate <> 1145832Sgblack@eecs.umich.edubool 1155832Sgblack@eecs.umich.eduparseParam(const string &s, float &value) 1165832Sgblack@eecs.umich.edu{ 1175832Sgblack@eecs.umich.edu return (sscanf(s.c_str(), "%f", &value) == 1); 1185832Sgblack@eecs.umich.edu} 1197903Shestness@cs.utexas.edu 1207903Shestness@cs.utexas.edutemplate <> 1217903Shestness@cs.utexas.edubool 1227903Shestness@cs.utexas.eduparseParam(const string &s, double &value) 1235832Sgblack@eecs.umich.edu{ 1245832Sgblack@eecs.umich.edu return (sscanf(s.c_str(), "%lf", &value) == 1); 1255832Sgblack@eecs.umich.edu} 1265832Sgblack@eecs.umich.edu 1275832Sgblack@eecs.umich.edutemplate <> 1285832Sgblack@eecs.umich.edubool 1295832Sgblack@eecs.umich.eduparseParam(const string &s, bool &value) 1305832Sgblack@eecs.umich.edu{ 1315832Sgblack@eecs.umich.edu const string &ls = to_lower(s); 1325832Sgblack@eecs.umich.edu 1335832Sgblack@eecs.umich.edu if (ls == "true") { 1345832Sgblack@eecs.umich.edu value = true; 1355832Sgblack@eecs.umich.edu return true; 1365832Sgblack@eecs.umich.edu } 1375832Sgblack@eecs.umich.edu 1385832Sgblack@eecs.umich.edu if (ls == "false") { 1395832Sgblack@eecs.umich.edu value = false; 1405832Sgblack@eecs.umich.edu return true; 1415832Sgblack@eecs.umich.edu } 1425832Sgblack@eecs.umich.edu 1435832Sgblack@eecs.umich.edu return false; 1445832Sgblack@eecs.umich.edu} 1455832Sgblack@eecs.umich.edu 1465832Sgblack@eecs.umich.edu// Display bools as strings 1475832Sgblack@eecs.umich.edutemplate <> 1485832Sgblack@eecs.umich.eduvoid 1495832Sgblack@eecs.umich.edushowParam(ostream &os, const bool &value) 1505832Sgblack@eecs.umich.edu{ 1515832Sgblack@eecs.umich.edu os << (value ? "true" : "false"); 1525832Sgblack@eecs.umich.edu} 1537903Shestness@cs.utexas.edu 1547903Shestness@cs.utexas.edu 1557903Shestness@cs.utexas.edu// String requires no processing to speak of 1567903Shestness@cs.utexas.edutemplate <> 1575832Sgblack@eecs.umich.edubool 1585832Sgblack@eecs.umich.eduparseParam(const string &s, string &value) 1595831Sgblack@eecs.umich.edu{ 1605831Sgblack@eecs.umich.edu value = s; 1615831Sgblack@eecs.umich.edu return true; 1625832Sgblack@eecs.umich.edu} 1635832Sgblack@eecs.umich.edu 1645832Sgblack@eecs.umich.eduint Serializable::ckptMaxCount = 0; 1655832Sgblack@eecs.umich.eduint Serializable::ckptCount = 0; 1665832Sgblack@eecs.umich.eduint Serializable::ckptPrevCount = -1; 1675832Sgblack@eecs.umich.edu 1685832Sgblack@eecs.umich.eduvoid 1695832Sgblack@eecs.umich.eduSerializable::nameOut(ostream &os) 1705832Sgblack@eecs.umich.edu{ 1715832Sgblack@eecs.umich.edu os << "\n[" << name() << "]\n"; 1725832Sgblack@eecs.umich.edu} 1735832Sgblack@eecs.umich.edu 1745832Sgblack@eecs.umich.eduvoid 1755832Sgblack@eecs.umich.eduSerializable::nameOut(ostream &os, const string &_name) 1765832Sgblack@eecs.umich.edu{ 1775832Sgblack@eecs.umich.edu os << "\n[" << _name << "]\n"; 1785832Sgblack@eecs.umich.edu} 1795832Sgblack@eecs.umich.edu 1805832Sgblack@eecs.umich.edutemplate <class T> 1815832Sgblack@eecs.umich.eduvoid 1825832Sgblack@eecs.umich.eduparamOut(ostream &os, const string &name, const T ¶m) 1835832Sgblack@eecs.umich.edu{ 1845832Sgblack@eecs.umich.edu os << name << "="; 1855832Sgblack@eecs.umich.edu showParam(os, param); 1865832Sgblack@eecs.umich.edu os << "\n"; 1875832Sgblack@eecs.umich.edu} 1885832Sgblack@eecs.umich.edu 1895832Sgblack@eecs.umich.edutemplate <class T> 1905832Sgblack@eecs.umich.eduvoid 1915832Sgblack@eecs.umich.eduarrayParamOut(ostream &os, const string &name, const vector<T> ¶m) 1925832Sgblack@eecs.umich.edu{ 1935832Sgblack@eecs.umich.edu typename vector<T>::size_type size = param.size(); 1945831Sgblack@eecs.umich.edu os << name << "="; 1955831Sgblack@eecs.umich.edu if (size > 0) 1965831Sgblack@eecs.umich.edu showParam(os, param[0]); 1975831Sgblack@eecs.umich.edu for (typename vector<T>::size_type i = 1; i < size; ++i) { 1985831Sgblack@eecs.umich.edu os << " "; 1995831Sgblack@eecs.umich.edu showParam(os, param[i]); 2005831Sgblack@eecs.umich.edu } 2015831Sgblack@eecs.umich.edu os << "\n"; 2025831Sgblack@eecs.umich.edu} 2035831Sgblack@eecs.umich.edu 2045831Sgblack@eecs.umich.edu 2055831Sgblack@eecs.umich.edutemplate <class T> 2065831Sgblack@eecs.umich.eduvoid 2075831Sgblack@eecs.umich.eduparamIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) 2085831Sgblack@eecs.umich.edu{ 2095831Sgblack@eecs.umich.edu string str; 2105831Sgblack@eecs.umich.edu if (!cp->find(section, name, str) || !parseParam(str, param)) { 2115831Sgblack@eecs.umich.edu fatal("Can't unserialize '%s:%s'\n", section, name); 2125831Sgblack@eecs.umich.edu } 2135831Sgblack@eecs.umich.edu} 2145831Sgblack@eecs.umich.edu 2155831Sgblack@eecs.umich.edutemplate <class T> 2165831Sgblack@eecs.umich.edubool 2175831Sgblack@eecs.umich.eduoptParamIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) 2185831Sgblack@eecs.umich.edu{ 2195831Sgblack@eecs.umich.edu string str; 2205831Sgblack@eecs.umich.edu if (!cp->find(section, name, str) || !parseParam(str, param)) { 2215831Sgblack@eecs.umich.edu warn("optional parameter %s:%s not present\n", section, name); 2225831Sgblack@eecs.umich.edu return false; 2235831Sgblack@eecs.umich.edu } else { 2245831Sgblack@eecs.umich.edu return true; 2255831Sgblack@eecs.umich.edu } 2265832Sgblack@eecs.umich.edu} 2275832Sgblack@eecs.umich.edu 2285831Sgblack@eecs.umich.edutemplate <class T> 2295832Sgblack@eecs.umich.eduvoid 2305832Sgblack@eecs.umich.eduarrayParamOut(ostream &os, const string &name, const T *param, unsigned size) 2315831Sgblack@eecs.umich.edu{ 2325832Sgblack@eecs.umich.edu os << name << "="; 2335831Sgblack@eecs.umich.edu if (size > 0) 2345831Sgblack@eecs.umich.edu showParam(os, param[0]); 2355831Sgblack@eecs.umich.edu for (unsigned i = 1; i < size; ++i) { 2365831Sgblack@eecs.umich.edu os << " "; 2375831Sgblack@eecs.umich.edu showParam(os, param[i]); 2385831Sgblack@eecs.umich.edu } 2395831Sgblack@eecs.umich.edu os << "\n"; 2405831Sgblack@eecs.umich.edu} 2415831Sgblack@eecs.umich.edu 2425831Sgblack@eecs.umich.edu 2435831Sgblack@eecs.umich.edutemplate <class T> 2445831Sgblack@eecs.umich.eduvoid 2455831Sgblack@eecs.umich.eduarrayParamIn(Checkpoint *cp, const string §ion, const string &name, 2465831Sgblack@eecs.umich.edu T *param, unsigned size) 2475832Sgblack@eecs.umich.edu{ 2485831Sgblack@eecs.umich.edu string str; 2495831Sgblack@eecs.umich.edu if (!cp->find(section, name, str)) { 2505831Sgblack@eecs.umich.edu fatal("Can't unserialize '%s:%s'\n", section, name); 2515831Sgblack@eecs.umich.edu } 2525831Sgblack@eecs.umich.edu 2535831Sgblack@eecs.umich.edu // code below stolen from VectorParam<T>::parse(). 2545831Sgblack@eecs.umich.edu // it would be nice to unify these somehow... 2555831Sgblack@eecs.umich.edu 2565831Sgblack@eecs.umich.edu vector<string> tokens; 2575831Sgblack@eecs.umich.edu 2585831Sgblack@eecs.umich.edu tokenize(tokens, str, ' '); 2595831Sgblack@eecs.umich.edu 2605831Sgblack@eecs.umich.edu // Need this if we were doing a vector 2615831Sgblack@eecs.umich.edu // value.resize(tokens.size()); 2625831Sgblack@eecs.umich.edu 2637903Shestness@cs.utexas.edu if (tokens.size() != size) { 2647903Shestness@cs.utexas.edu fatal("Array size mismatch on %s:%s'\n", section, name); 2657903Shestness@cs.utexas.edu } 2665831Sgblack@eecs.umich.edu 2675831Sgblack@eecs.umich.edu for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 2687811Ssteve.reinhardt@amd.com // need to parse into local variable to handle vector<bool>, 2695831Sgblack@eecs.umich.edu // for which operator[] returns a special reference class 2705831Sgblack@eecs.umich.edu // that's not the same as 'bool&', (since it's a packed 271 // vector) 272 T scalar_value = 0; 273 if (!parseParam(tokens[i], scalar_value)) { 274 string err("could not parse \""); 275 276 err += str; 277 err += "\""; 278 279 fatal(err); 280 } 281 282 // assign parsed value to vector 283 param[i] = scalar_value; 284 } 285} 286 287template <class T> 288void 289arrayParamIn(Checkpoint *cp, const string §ion, 290 const string &name, vector<T> ¶m) 291{ 292 string str; 293 if (!cp->find(section, name, str)) { 294 fatal("Can't unserialize '%s:%s'\n", section, name); 295 } 296 297 // code below stolen from VectorParam<T>::parse(). 298 // it would be nice to unify these somehow... 299 300 vector<string> tokens; 301 302 tokenize(tokens, str, ' '); 303 304 // Need this if we were doing a vector 305 // value.resize(tokens.size()); 306 307 param.resize(tokens.size()); 308 309 for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 310 // need to parse into local variable to handle vector<bool>, 311 // for which operator[] returns a special reference class 312 // that's not the same as 'bool&', (since it's a packed 313 // vector) 314 T scalar_value = 0; 315 if (!parseParam(tokens[i], scalar_value)) { 316 string err("could not parse \""); 317 318 err += str; 319 err += "\""; 320 321 fatal(err); 322 } 323 324 // assign parsed value to vector 325 param[i] = scalar_value; 326 } 327} 328 329void 330objParamIn(Checkpoint *cp, const string §ion, 331 const string &name, SimObject * ¶m) 332{ 333 if (!cp->findObj(section, name, param)) { 334 fatal("Can't unserialize '%s:%s'\n", section, name); 335 } 336} 337 338 339#define INSTANTIATE_PARAM_TEMPLATES(type) \ 340template void \ 341paramOut(ostream &os, const string &name, type const ¶m); \ 342template void \ 343paramIn(Checkpoint *cp, const string §ion, \ 344 const string &name, type & param); \ 345template bool \ 346optParamIn(Checkpoint *cp, const string §ion, \ 347 const string &name, type & param); \ 348template void \ 349arrayParamOut(ostream &os, const string &name, \ 350 type const *param, unsigned size); \ 351template void \ 352arrayParamIn(Checkpoint *cp, const string §ion, \ 353 const string &name, type *param, unsigned size); \ 354template void \ 355arrayParamOut(ostream &os, const string &name, \ 356 const vector<type> ¶m); \ 357template void \ 358arrayParamIn(Checkpoint *cp, const string §ion, \ 359 const string &name, vector<type> ¶m); 360 361INSTANTIATE_PARAM_TEMPLATES(char) 362INSTANTIATE_PARAM_TEMPLATES(signed char) 363INSTANTIATE_PARAM_TEMPLATES(unsigned char) 364INSTANTIATE_PARAM_TEMPLATES(signed short) 365INSTANTIATE_PARAM_TEMPLATES(unsigned short) 366INSTANTIATE_PARAM_TEMPLATES(signed int) 367INSTANTIATE_PARAM_TEMPLATES(unsigned int) 368INSTANTIATE_PARAM_TEMPLATES(signed long) 369INSTANTIATE_PARAM_TEMPLATES(unsigned long) 370INSTANTIATE_PARAM_TEMPLATES(signed long long) 371INSTANTIATE_PARAM_TEMPLATES(unsigned long long) 372INSTANTIATE_PARAM_TEMPLATES(bool) 373INSTANTIATE_PARAM_TEMPLATES(float) 374INSTANTIATE_PARAM_TEMPLATES(double) 375INSTANTIATE_PARAM_TEMPLATES(string) 376 377 378///////////////////////////// 379 380/// Container for serializing global variables (not associated with 381/// any serialized object). 382class Globals : public Serializable 383{ 384 public: 385 const string name() const; 386 void serialize(ostream &os); 387 void unserialize(Checkpoint *cp); 388}; 389 390/// The one and only instance of the Globals class. 391Globals globals; 392 393const string 394Globals::name() const 395{ 396 return "Globals"; 397} 398 399void 400Globals::serialize(ostream &os) 401{ 402 nameOut(os); 403 SERIALIZE_SCALAR(curTick()); 404 405 nameOut(os, "MainEventQueue"); 406 mainEventQueue.serialize(os); 407} 408 409void 410Globals::unserialize(Checkpoint *cp) 411{ 412 const string §ion = name(); 413 Tick tick; 414 paramIn(cp, section, "curTick", tick); 415 curTick(tick); 416 417 mainEventQueue.unserialize(cp, "MainEventQueue"); 418} 419 420Serializable::Serializable() 421{ 422} 423 424Serializable::~Serializable() 425{ 426} 427 428void 429Serializable::serialize(ostream &os) 430{ 431} 432 433void 434Serializable::unserialize(Checkpoint *cp, const string §ion) 435{ 436} 437 438void 439Serializable::serializeAll(const string &cpt_dir) 440{ 441 string dir = Checkpoint::setDir(cpt_dir); 442 if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) 443 fatal("couldn't mkdir %s\n", dir); 444 445 string cpt_file = dir + Checkpoint::baseFilename; 446 ofstream outstream(cpt_file.c_str()); 447 time_t t = time(NULL); 448 if (!outstream.is_open()) 449 fatal("Unable to open file %s for writing\n", cpt_file.c_str()); 450 outstream << "## checkpoint generated: " << ctime(&t); 451 452 globals.serialize(outstream); 453 SimObject::serializeAll(outstream); 454} 455 456void 457Serializable::unserializeGlobals(Checkpoint *cp) 458{ 459 globals.unserialize(cp); 460} 461 462void 463debug_serialize(const string &cpt_dir) 464{ 465 Serializable::serializeAll(cpt_dir); 466} 467 468 469//////////////////////////////////////////////////////////////////////// 470// 471// SerializableClass member definitions 472// 473//////////////////////////////////////////////////////////////////////// 474 475// Map of class names to SerializableBuilder creation functions. 476// Need to make this a pointer so we can force initialization on the 477// first reference; otherwise, some SerializableClass constructors 478// may be invoked before the classMap constructor. 479map<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0; 480 481// SerializableClass constructor: add mapping to classMap 482SerializableClass::SerializableClass(const string &className, 483 CreateFunc createFunc) 484{ 485 if (classMap == NULL) 486 classMap = new map<string, SerializableClass::CreateFunc>(); 487 488 if ((*classMap)[className]) 489 fatal("Error: simulation object class %s redefined\n", className); 490 491 // add className --> createFunc to class map 492 (*classMap)[className] = createFunc; 493} 494 495// 496// 497Serializable * 498SerializableClass::createObject(Checkpoint *cp, const string §ion) 499{ 500 string className; 501 502 if (!cp->find(section, "type", className)) { 503 fatal("Serializable::create: no 'type' entry in section '%s'.\n", 504 section); 505 } 506 507 CreateFunc createFunc = (*classMap)[className]; 508 509 if (createFunc == NULL) { 510 fatal("Serializable::create: no create function for class '%s'.\n", 511 className); 512 } 513 514 Serializable *object = createFunc(cp, section); 515 516 assert(object != NULL); 517 518 return object; 519} 520 521 522Serializable * 523Serializable::create(Checkpoint *cp, const string §ion) 524{ 525 Serializable *object = SerializableClass::createObject(cp, section); 526 object->unserialize(cp, section); 527 return object; 528} 529 530 531const char *Checkpoint::baseFilename = "m5.cpt"; 532 533string Checkpoint::currentDirectory; 534 535string 536Checkpoint::setDir(const string &name) 537{ 538 // use csprintf to insert curTick() into directory name if it 539 // appears to have a format placeholder in it. 540 currentDirectory = (name.find("%") != string::npos) ? 541 csprintf(name, curTick()) : name; 542 if (currentDirectory[currentDirectory.size() - 1] != '/') 543 currentDirectory += "/"; 544 return currentDirectory; 545} 546 547string 548Checkpoint::dir() 549{ 550 return currentDirectory; 551} 552 553 554Checkpoint::Checkpoint(const string &cpt_dir) 555 : db(new IniFile), cptDir(setDir(cpt_dir)) 556{ 557 string filename = cptDir + "/" + Checkpoint::baseFilename; 558 if (!db->load(filename)) { 559 fatal("Can't load checkpoint file '%s'\n", filename); 560 } 561} 562 563 564bool 565Checkpoint::find(const string §ion, const string &entry, string &value) 566{ 567 return db->find(section, entry, value); 568} 569 570 571bool 572Checkpoint::findObj(const string §ion, const string &entry, 573 SimObject *&value) 574{ 575 string path; 576 577 if (!db->find(section, entry, path)) 578 return false; 579 580 value = resolveSimObject(path); 581 return true; 582} 583 584 585bool 586Checkpoint::sectionExists(const string §ion) 587{ 588 return db->sectionExists(section); 589} 590