1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * Copyright (c) 2013 Mark D. Hill and David A. Wood 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer; 11 * redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution; 14 * neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Authors: Nathan Binkert 31 * Erik Hallnor 32 * Steve Reinhardt 33 */ 34 35#include <sys/stat.h> 36#include <sys/time.h> 37#include <sys/types.h> 38 39#include <cerrno> 40#include <fstream> 41#include <list> 42#include <string> 43#include <vector> 44 45#include "base/inifile.hh" 46#include "base/misc.hh" 47#include "base/output.hh" 48#include "base/str.hh" 49#include "base/trace.hh" 50#include "sim/eventq.hh" 51#include "sim/serialize.hh" 52#include "sim/sim_events.hh" 53#include "sim/sim_exit.hh" 54#include "sim/sim_object.hh" 55 56// For stat reset hack 57#include "sim/stat_control.hh" 58 59using namespace std; 60 61extern SimObject *resolveSimObject(const string &); 62 63// 64// The base implementations use to_number for parsing and '<<' for 65// displaying, suitable for integer types. 66// 67template <class T> 68bool 69parseParam(const string &s, T &value) 70{ 71 return to_number(s, value); 72} 73 74template <class T> 75void 76showParam(ostream &os, const T &value) 77{ 78 os << value; 79} 80 81// 82// Template specializations: 83// - char (8-bit integer) 84// - floating-point types 85// - bool 86// - string 87// 88 89// Treat 8-bit ints (chars) as ints on output, not as chars 90template <> 91void 92showParam(ostream &os, const char &value) 93{ 94 os << (int)value; 95} 96 97 98template <> 99void 100showParam(ostream &os, const signed char &value) 101{ 102 os << (int)value; 103} 104 105 106template <> 107void 108showParam(ostream &os, const unsigned char &value) 109{ 110 os << (unsigned int)value; 111} 112 113
| 1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * Copyright (c) 2013 Mark D. Hill and David A. Wood 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer; 11 * redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution; 14 * neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Authors: Nathan Binkert 31 * Erik Hallnor 32 * Steve Reinhardt 33 */ 34 35#include <sys/stat.h> 36#include <sys/time.h> 37#include <sys/types.h> 38 39#include <cerrno> 40#include <fstream> 41#include <list> 42#include <string> 43#include <vector> 44 45#include "base/inifile.hh" 46#include "base/misc.hh" 47#include "base/output.hh" 48#include "base/str.hh" 49#include "base/trace.hh" 50#include "sim/eventq.hh" 51#include "sim/serialize.hh" 52#include "sim/sim_events.hh" 53#include "sim/sim_exit.hh" 54#include "sim/sim_object.hh" 55 56// For stat reset hack 57#include "sim/stat_control.hh" 58 59using namespace std; 60 61extern SimObject *resolveSimObject(const string &); 62 63// 64// The base implementations use to_number for parsing and '<<' for 65// displaying, suitable for integer types. 66// 67template <class T> 68bool 69parseParam(const string &s, T &value) 70{ 71 return to_number(s, value); 72} 73 74template <class T> 75void 76showParam(ostream &os, const T &value) 77{ 78 os << value; 79} 80 81// 82// Template specializations: 83// - char (8-bit integer) 84// - floating-point types 85// - bool 86// - string 87// 88 89// Treat 8-bit ints (chars) as ints on output, not as chars 90template <> 91void 92showParam(ostream &os, const char &value) 93{ 94 os << (int)value; 95} 96 97 98template <> 99void 100showParam(ostream &os, const signed char &value) 101{ 102 os << (int)value; 103} 104 105 106template <> 107void 108showParam(ostream &os, const unsigned char &value) 109{ 110 os << (unsigned int)value; 111} 112 113
|
146} 147 148// Display bools as strings 149template <> 150void 151showParam(ostream &os, const bool &value) 152{ 153 os << (value ? "true" : "false"); 154} 155 156 157// String requires no processing to speak of 158template <> 159bool 160parseParam(const string &s, string &value) 161{ 162 value = s; 163 return true; 164} 165 166int Serializable::ckptMaxCount = 0; 167int Serializable::ckptCount = 0; 168int Serializable::ckptPrevCount = -1; 169 170void 171Serializable::nameOut(ostream &os) 172{ 173 os << "\n[" << name() << "]\n"; 174} 175 176void 177Serializable::nameOut(ostream &os, const string &_name) 178{ 179 os << "\n[" << _name << "]\n"; 180} 181 182template <class T> 183void 184paramOut(ostream &os, const string &name, const T ¶m) 185{ 186 os << name << "="; 187 showParam(os, param); 188 os << "\n"; 189} 190 191template <class T> 192void 193arrayParamOut(ostream &os, const string &name, const vector<T> ¶m) 194{ 195 typename vector<T>::size_type size = param.size(); 196 os << name << "="; 197 if (size > 0) 198 showParam(os, param[0]); 199 for (typename vector<T>::size_type i = 1; i < size; ++i) { 200 os << " "; 201 showParam(os, param[i]); 202 } 203 os << "\n"; 204} 205 206template <class T> 207void 208arrayParamOut(ostream &os, const string &name, const list<T> ¶m) 209{ 210 typename list<T>::const_iterator it = param.begin(); 211 212 os << name << "="; 213 if (param.size() > 0) 214 showParam(os, *it); 215 it++; 216 while (it != param.end()) { 217 os << " "; 218 showParam(os, *it); 219 it++; 220 } 221 os << "\n"; 222} 223 224template <class T> 225void 226paramIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) 227{ 228 string str; 229 if (!cp->find(section, name, str) || !parseParam(str, param)) { 230 fatal("Can't unserialize '%s:%s'\n", section, name); 231 } 232} 233 234template <class T> 235bool 236optParamIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) 237{ 238 string str; 239 if (!cp->find(section, name, str) || !parseParam(str, param)) { 240 warn("optional parameter %s:%s not present\n", section, name); 241 return false; 242 } else { 243 return true; 244 } 245} 246 247template <class T> 248void 249arrayParamOut(ostream &os, const string &name, const T *param, unsigned size) 250{ 251 os << name << "="; 252 if (size > 0) 253 showParam(os, param[0]); 254 for (unsigned i = 1; i < size; ++i) { 255 os << " "; 256 showParam(os, param[i]); 257 } 258 os << "\n"; 259} 260 261 262template <class T> 263void 264arrayParamIn(Checkpoint *cp, const string §ion, const string &name, 265 T *param, unsigned size) 266{ 267 string str; 268 if (!cp->find(section, name, str)) { 269 fatal("Can't unserialize '%s:%s'\n", section, name); 270 } 271 272 // code below stolen from VectorParam<T>::parse(). 273 // it would be nice to unify these somehow... 274 275 vector<string> tokens; 276 277 tokenize(tokens, str, ' '); 278 279 // Need this if we were doing a vector 280 // value.resize(tokens.size()); 281 282 if (tokens.size() != size) { 283 fatal("Array size mismatch on %s:%s'\n", section, name); 284 } 285 286 for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 287 // need to parse into local variable to handle vector<bool>, 288 // for which operator[] returns a special reference class 289 // that's not the same as 'bool&', (since it's a packed 290 // vector) 291 T scalar_value = 0; 292 if (!parseParam(tokens[i], scalar_value)) { 293 string err("could not parse \""); 294 295 err += str; 296 err += "\""; 297 298 fatal(err); 299 } 300 301 // assign parsed value to vector 302 param[i] = scalar_value; 303 } 304} 305 306template <class T> 307void 308arrayParamIn(Checkpoint *cp, const string §ion, 309 const string &name, vector<T> ¶m) 310{ 311 string str; 312 if (!cp->find(section, name, str)) { 313 fatal("Can't unserialize '%s:%s'\n", section, name); 314 } 315 316 // code below stolen from VectorParam<T>::parse(). 317 // it would be nice to unify these somehow... 318 319 vector<string> tokens; 320 321 tokenize(tokens, str, ' '); 322 323 // Need this if we were doing a vector 324 // value.resize(tokens.size()); 325 326 param.resize(tokens.size()); 327 328 for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 329 // need to parse into local variable to handle vector<bool>, 330 // for which operator[] returns a special reference class 331 // that's not the same as 'bool&', (since it's a packed 332 // vector) 333 T scalar_value = 0; 334 if (!parseParam(tokens[i], scalar_value)) { 335 string err("could not parse \""); 336 337 err += str; 338 err += "\""; 339 340 fatal(err); 341 } 342 343 // assign parsed value to vector 344 param[i] = scalar_value; 345 } 346} 347 348template <class T> 349void 350arrayParamIn(Checkpoint *cp, const string §ion, 351 const string &name, list<T> ¶m) 352{ 353 string str; 354 if (!cp->find(section, name, str)) { 355 fatal("Can't unserialize '%s:%s'\n", section, name); 356 } 357 param.clear(); 358 359 vector<string> tokens; 360 tokenize(tokens, str, ' '); 361 362 for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 363 T scalar_value = 0; 364 if (!parseParam(tokens[i], scalar_value)) { 365 string err("could not parse \""); 366 367 err += str; 368 err += "\""; 369 370 fatal(err); 371 } 372 373 // assign parsed value to vector 374 param.push_back(scalar_value); 375 } 376} 377 378 379void 380objParamIn(Checkpoint *cp, const string §ion, 381 const string &name, SimObject * ¶m) 382{ 383 if (!cp->findObj(section, name, param)) { 384 fatal("Can't unserialize '%s:%s'\n", section, name); 385 } 386} 387 388 389#define INSTANTIATE_PARAM_TEMPLATES(type) \ 390template void \ 391paramOut(ostream &os, const string &name, type const ¶m); \ 392template void \ 393paramIn(Checkpoint *cp, const string §ion, \ 394 const string &name, type & param); \ 395template bool \ 396optParamIn(Checkpoint *cp, const string §ion, \ 397 const string &name, type & param); \ 398template void \ 399arrayParamOut(ostream &os, const string &name, \ 400 type const *param, unsigned size); \ 401template void \ 402arrayParamIn(Checkpoint *cp, const string §ion, \ 403 const string &name, type *param, unsigned size); \ 404template void \ 405arrayParamOut(ostream &os, const string &name, \ 406 const vector<type> ¶m); \ 407template void \ 408arrayParamIn(Checkpoint *cp, const string §ion, \ 409 const string &name, vector<type> ¶m); \ 410template void \ 411arrayParamOut(ostream &os, const string &name, \ 412 const list<type> ¶m); \ 413template void \ 414arrayParamIn(Checkpoint *cp, const string §ion, \ 415 const string &name, list<type> ¶m); 416 417INSTANTIATE_PARAM_TEMPLATES(char) 418INSTANTIATE_PARAM_TEMPLATES(signed char) 419INSTANTIATE_PARAM_TEMPLATES(unsigned char) 420INSTANTIATE_PARAM_TEMPLATES(signed short) 421INSTANTIATE_PARAM_TEMPLATES(unsigned short) 422INSTANTIATE_PARAM_TEMPLATES(signed int) 423INSTANTIATE_PARAM_TEMPLATES(unsigned int) 424INSTANTIATE_PARAM_TEMPLATES(signed long) 425INSTANTIATE_PARAM_TEMPLATES(unsigned long) 426INSTANTIATE_PARAM_TEMPLATES(signed long long) 427INSTANTIATE_PARAM_TEMPLATES(unsigned long long) 428INSTANTIATE_PARAM_TEMPLATES(bool) 429INSTANTIATE_PARAM_TEMPLATES(float) 430INSTANTIATE_PARAM_TEMPLATES(double) 431INSTANTIATE_PARAM_TEMPLATES(string) 432 433 434///////////////////////////// 435 436/// Container for serializing global variables (not associated with 437/// any serialized object). 438class Globals : public Serializable 439{ 440 public: 441 const string name() const; 442 void serialize(ostream &os); 443 void unserialize(Checkpoint *cp, const std::string §ion); 444}; 445 446/// The one and only instance of the Globals class. 447Globals globals; 448 449const string 450Globals::name() const 451{ 452 return "Globals"; 453} 454 455void 456Globals::serialize(ostream &os) 457{ 458 nameOut(os); 459 paramOut(os, "curTick", curTick()); 460 461 paramOut(os, "numMainEventQueues", numMainEventQueues); 462 463 for (uint32_t i = 0; i < numMainEventQueues; ++i) { 464 nameOut(os, "MainEventQueue"); 465 mainEventQueue[i]->serialize(os); 466 } 467} 468 469void 470Globals::unserialize(Checkpoint *cp, const std::string §ion) 471{ 472 Tick tick; 473 paramIn(cp, section, "curTick", tick); 474 paramIn(cp, section, "numMainEventQueues", numMainEventQueues); 475 476 for (uint32_t i = 0; i < numMainEventQueues; ++i) { 477 mainEventQueue[i]->setCurTick(tick); 478 mainEventQueue[i]->unserialize(cp, "MainEventQueue"); 479 } 480} 481 482Serializable::Serializable() 483{ 484} 485 486Serializable::~Serializable() 487{ 488} 489 490void 491Serializable::serialize(ostream &os) 492{ 493} 494 495void 496Serializable::unserialize(Checkpoint *cp, const string §ion) 497{ 498} 499 500void 501Serializable::serializeAll(const string &cpt_dir) 502{ 503 string dir = Checkpoint::setDir(cpt_dir); 504 if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) 505 fatal("couldn't mkdir %s\n", dir); 506 507 string cpt_file = dir + Checkpoint::baseFilename; 508 ofstream outstream(cpt_file.c_str()); 509 time_t t = time(NULL); 510 if (!outstream.is_open()) 511 fatal("Unable to open file %s for writing\n", cpt_file.c_str()); 512 outstream << "## checkpoint generated: " << ctime(&t); 513 514 globals.serialize(outstream); 515 SimObject::serializeAll(outstream); 516} 517 518void 519Serializable::unserializeGlobals(Checkpoint *cp) 520{ 521 globals.unserialize(cp, globals.name()); 522} 523 524void 525debug_serialize(const string &cpt_dir) 526{ 527 Serializable::serializeAll(cpt_dir); 528} 529 530 531//////////////////////////////////////////////////////////////////////// 532// 533// SerializableClass member definitions 534// 535//////////////////////////////////////////////////////////////////////// 536 537// Map of class names to SerializableBuilder creation functions. 538// Need to make this a pointer so we can force initialization on the 539// first reference; otherwise, some SerializableClass constructors 540// may be invoked before the classMap constructor. 541map<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0; 542 543// SerializableClass constructor: add mapping to classMap 544SerializableClass::SerializableClass(const string &className, 545 CreateFunc createFunc) 546{ 547 if (classMap == NULL) 548 classMap = new map<string, SerializableClass::CreateFunc>(); 549 550 if ((*classMap)[className]) 551 fatal("Error: simulation object class %s redefined\n", className); 552 553 // add className --> createFunc to class map 554 (*classMap)[className] = createFunc; 555} 556 557// 558// 559Serializable * 560SerializableClass::createObject(Checkpoint *cp, const string §ion) 561{ 562 string className; 563 564 if (!cp->find(section, "type", className)) { 565 fatal("Serializable::create: no 'type' entry in section '%s'.\n", 566 section); 567 } 568 569 CreateFunc createFunc = (*classMap)[className]; 570 571 if (createFunc == NULL) { 572 fatal("Serializable::create: no create function for class '%s'.\n", 573 className); 574 } 575 576 Serializable *object = createFunc(cp, section); 577 578 assert(object != NULL); 579 580 return object; 581} 582 583 584Serializable * 585Serializable::create(Checkpoint *cp, const string §ion) 586{ 587 Serializable *object = SerializableClass::createObject(cp, section); 588 object->unserialize(cp, section); 589 return object; 590} 591 592 593const char *Checkpoint::baseFilename = "m5.cpt"; 594 595string Checkpoint::currentDirectory; 596 597string 598Checkpoint::setDir(const string &name) 599{ 600 // use csprintf to insert curTick() into directory name if it 601 // appears to have a format placeholder in it. 602 currentDirectory = (name.find("%") != string::npos) ? 603 csprintf(name, curTick()) : name; 604 if (currentDirectory[currentDirectory.size() - 1] != '/') 605 currentDirectory += "/"; 606 return currentDirectory; 607} 608 609string 610Checkpoint::dir() 611{ 612 return currentDirectory; 613} 614 615 616Checkpoint::Checkpoint(const string &cpt_dir) 617 : db(new IniFile), cptDir(setDir(cpt_dir)) 618{ 619 string filename = cptDir + "/" + Checkpoint::baseFilename; 620 if (!db->load(filename)) { 621 fatal("Can't load checkpoint file '%s'\n", filename); 622 } 623} 624 625Checkpoint::~Checkpoint() 626{ 627 delete db; 628} 629 630bool 631Checkpoint::find(const string §ion, const string &entry, string &value) 632{ 633 return db->find(section, entry, value); 634} 635 636 637bool 638Checkpoint::findObj(const string §ion, const string &entry, 639 SimObject *&value) 640{ 641 string path; 642 643 if (!db->find(section, entry, path)) 644 return false; 645 646 value = resolveSimObject(path); 647 return true; 648} 649 650 651bool 652Checkpoint::sectionExists(const string §ion) 653{ 654 return db->sectionExists(section); 655}
| 133} 134 135// Display bools as strings 136template <> 137void 138showParam(ostream &os, const bool &value) 139{ 140 os << (value ? "true" : "false"); 141} 142 143 144// String requires no processing to speak of 145template <> 146bool 147parseParam(const string &s, string &value) 148{ 149 value = s; 150 return true; 151} 152 153int Serializable::ckptMaxCount = 0; 154int Serializable::ckptCount = 0; 155int Serializable::ckptPrevCount = -1; 156 157void 158Serializable::nameOut(ostream &os) 159{ 160 os << "\n[" << name() << "]\n"; 161} 162 163void 164Serializable::nameOut(ostream &os, const string &_name) 165{ 166 os << "\n[" << _name << "]\n"; 167} 168 169template <class T> 170void 171paramOut(ostream &os, const string &name, const T ¶m) 172{ 173 os << name << "="; 174 showParam(os, param); 175 os << "\n"; 176} 177 178template <class T> 179void 180arrayParamOut(ostream &os, const string &name, const vector<T> ¶m) 181{ 182 typename vector<T>::size_type size = param.size(); 183 os << name << "="; 184 if (size > 0) 185 showParam(os, param[0]); 186 for (typename vector<T>::size_type i = 1; i < size; ++i) { 187 os << " "; 188 showParam(os, param[i]); 189 } 190 os << "\n"; 191} 192 193template <class T> 194void 195arrayParamOut(ostream &os, const string &name, const list<T> ¶m) 196{ 197 typename list<T>::const_iterator it = param.begin(); 198 199 os << name << "="; 200 if (param.size() > 0) 201 showParam(os, *it); 202 it++; 203 while (it != param.end()) { 204 os << " "; 205 showParam(os, *it); 206 it++; 207 } 208 os << "\n"; 209} 210 211template <class T> 212void 213paramIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) 214{ 215 string str; 216 if (!cp->find(section, name, str) || !parseParam(str, param)) { 217 fatal("Can't unserialize '%s:%s'\n", section, name); 218 } 219} 220 221template <class T> 222bool 223optParamIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) 224{ 225 string str; 226 if (!cp->find(section, name, str) || !parseParam(str, param)) { 227 warn("optional parameter %s:%s not present\n", section, name); 228 return false; 229 } else { 230 return true; 231 } 232} 233 234template <class T> 235void 236arrayParamOut(ostream &os, const string &name, const T *param, unsigned size) 237{ 238 os << name << "="; 239 if (size > 0) 240 showParam(os, param[0]); 241 for (unsigned i = 1; i < size; ++i) { 242 os << " "; 243 showParam(os, param[i]); 244 } 245 os << "\n"; 246} 247 248 249template <class T> 250void 251arrayParamIn(Checkpoint *cp, const string §ion, const string &name, 252 T *param, unsigned size) 253{ 254 string str; 255 if (!cp->find(section, name, str)) { 256 fatal("Can't unserialize '%s:%s'\n", section, name); 257 } 258 259 // code below stolen from VectorParam<T>::parse(). 260 // it would be nice to unify these somehow... 261 262 vector<string> tokens; 263 264 tokenize(tokens, str, ' '); 265 266 // Need this if we were doing a vector 267 // value.resize(tokens.size()); 268 269 if (tokens.size() != size) { 270 fatal("Array size mismatch on %s:%s'\n", section, name); 271 } 272 273 for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 274 // need to parse into local variable to handle vector<bool>, 275 // for which operator[] returns a special reference class 276 // that's not the same as 'bool&', (since it's a packed 277 // vector) 278 T scalar_value = 0; 279 if (!parseParam(tokens[i], scalar_value)) { 280 string err("could not parse \""); 281 282 err += str; 283 err += "\""; 284 285 fatal(err); 286 } 287 288 // assign parsed value to vector 289 param[i] = scalar_value; 290 } 291} 292 293template <class T> 294void 295arrayParamIn(Checkpoint *cp, const string §ion, 296 const string &name, vector<T> ¶m) 297{ 298 string str; 299 if (!cp->find(section, name, str)) { 300 fatal("Can't unserialize '%s:%s'\n", section, name); 301 } 302 303 // code below stolen from VectorParam<T>::parse(). 304 // it would be nice to unify these somehow... 305 306 vector<string> tokens; 307 308 tokenize(tokens, str, ' '); 309 310 // Need this if we were doing a vector 311 // value.resize(tokens.size()); 312 313 param.resize(tokens.size()); 314 315 for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 316 // need to parse into local variable to handle vector<bool>, 317 // for which operator[] returns a special reference class 318 // that's not the same as 'bool&', (since it's a packed 319 // vector) 320 T scalar_value = 0; 321 if (!parseParam(tokens[i], scalar_value)) { 322 string err("could not parse \""); 323 324 err += str; 325 err += "\""; 326 327 fatal(err); 328 } 329 330 // assign parsed value to vector 331 param[i] = scalar_value; 332 } 333} 334 335template <class T> 336void 337arrayParamIn(Checkpoint *cp, const string §ion, 338 const string &name, list<T> ¶m) 339{ 340 string str; 341 if (!cp->find(section, name, str)) { 342 fatal("Can't unserialize '%s:%s'\n", section, name); 343 } 344 param.clear(); 345 346 vector<string> tokens; 347 tokenize(tokens, str, ' '); 348 349 for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 350 T scalar_value = 0; 351 if (!parseParam(tokens[i], scalar_value)) { 352 string err("could not parse \""); 353 354 err += str; 355 err += "\""; 356 357 fatal(err); 358 } 359 360 // assign parsed value to vector 361 param.push_back(scalar_value); 362 } 363} 364 365 366void 367objParamIn(Checkpoint *cp, const string §ion, 368 const string &name, SimObject * ¶m) 369{ 370 if (!cp->findObj(section, name, param)) { 371 fatal("Can't unserialize '%s:%s'\n", section, name); 372 } 373} 374 375 376#define INSTANTIATE_PARAM_TEMPLATES(type) \ 377template void \ 378paramOut(ostream &os, const string &name, type const ¶m); \ 379template void \ 380paramIn(Checkpoint *cp, const string §ion, \ 381 const string &name, type & param); \ 382template bool \ 383optParamIn(Checkpoint *cp, const string §ion, \ 384 const string &name, type & param); \ 385template void \ 386arrayParamOut(ostream &os, const string &name, \ 387 type const *param, unsigned size); \ 388template void \ 389arrayParamIn(Checkpoint *cp, const string §ion, \ 390 const string &name, type *param, unsigned size); \ 391template void \ 392arrayParamOut(ostream &os, const string &name, \ 393 const vector<type> ¶m); \ 394template void \ 395arrayParamIn(Checkpoint *cp, const string §ion, \ 396 const string &name, vector<type> ¶m); \ 397template void \ 398arrayParamOut(ostream &os, const string &name, \ 399 const list<type> ¶m); \ 400template void \ 401arrayParamIn(Checkpoint *cp, const string §ion, \ 402 const string &name, list<type> ¶m); 403 404INSTANTIATE_PARAM_TEMPLATES(char) 405INSTANTIATE_PARAM_TEMPLATES(signed char) 406INSTANTIATE_PARAM_TEMPLATES(unsigned char) 407INSTANTIATE_PARAM_TEMPLATES(signed short) 408INSTANTIATE_PARAM_TEMPLATES(unsigned short) 409INSTANTIATE_PARAM_TEMPLATES(signed int) 410INSTANTIATE_PARAM_TEMPLATES(unsigned int) 411INSTANTIATE_PARAM_TEMPLATES(signed long) 412INSTANTIATE_PARAM_TEMPLATES(unsigned long) 413INSTANTIATE_PARAM_TEMPLATES(signed long long) 414INSTANTIATE_PARAM_TEMPLATES(unsigned long long) 415INSTANTIATE_PARAM_TEMPLATES(bool) 416INSTANTIATE_PARAM_TEMPLATES(float) 417INSTANTIATE_PARAM_TEMPLATES(double) 418INSTANTIATE_PARAM_TEMPLATES(string) 419 420 421///////////////////////////// 422 423/// Container for serializing global variables (not associated with 424/// any serialized object). 425class Globals : public Serializable 426{ 427 public: 428 const string name() const; 429 void serialize(ostream &os); 430 void unserialize(Checkpoint *cp, const std::string §ion); 431}; 432 433/// The one and only instance of the Globals class. 434Globals globals; 435 436const string 437Globals::name() const 438{ 439 return "Globals"; 440} 441 442void 443Globals::serialize(ostream &os) 444{ 445 nameOut(os); 446 paramOut(os, "curTick", curTick()); 447 448 paramOut(os, "numMainEventQueues", numMainEventQueues); 449 450 for (uint32_t i = 0; i < numMainEventQueues; ++i) { 451 nameOut(os, "MainEventQueue"); 452 mainEventQueue[i]->serialize(os); 453 } 454} 455 456void 457Globals::unserialize(Checkpoint *cp, const std::string §ion) 458{ 459 Tick tick; 460 paramIn(cp, section, "curTick", tick); 461 paramIn(cp, section, "numMainEventQueues", numMainEventQueues); 462 463 for (uint32_t i = 0; i < numMainEventQueues; ++i) { 464 mainEventQueue[i]->setCurTick(tick); 465 mainEventQueue[i]->unserialize(cp, "MainEventQueue"); 466 } 467} 468 469Serializable::Serializable() 470{ 471} 472 473Serializable::~Serializable() 474{ 475} 476 477void 478Serializable::serialize(ostream &os) 479{ 480} 481 482void 483Serializable::unserialize(Checkpoint *cp, const string §ion) 484{ 485} 486 487void 488Serializable::serializeAll(const string &cpt_dir) 489{ 490 string dir = Checkpoint::setDir(cpt_dir); 491 if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) 492 fatal("couldn't mkdir %s\n", dir); 493 494 string cpt_file = dir + Checkpoint::baseFilename; 495 ofstream outstream(cpt_file.c_str()); 496 time_t t = time(NULL); 497 if (!outstream.is_open()) 498 fatal("Unable to open file %s for writing\n", cpt_file.c_str()); 499 outstream << "## checkpoint generated: " << ctime(&t); 500 501 globals.serialize(outstream); 502 SimObject::serializeAll(outstream); 503} 504 505void 506Serializable::unserializeGlobals(Checkpoint *cp) 507{ 508 globals.unserialize(cp, globals.name()); 509} 510 511void 512debug_serialize(const string &cpt_dir) 513{ 514 Serializable::serializeAll(cpt_dir); 515} 516 517 518//////////////////////////////////////////////////////////////////////// 519// 520// SerializableClass member definitions 521// 522//////////////////////////////////////////////////////////////////////// 523 524// Map of class names to SerializableBuilder creation functions. 525// Need to make this a pointer so we can force initialization on the 526// first reference; otherwise, some SerializableClass constructors 527// may be invoked before the classMap constructor. 528map<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0; 529 530// SerializableClass constructor: add mapping to classMap 531SerializableClass::SerializableClass(const string &className, 532 CreateFunc createFunc) 533{ 534 if (classMap == NULL) 535 classMap = new map<string, SerializableClass::CreateFunc>(); 536 537 if ((*classMap)[className]) 538 fatal("Error: simulation object class %s redefined\n", className); 539 540 // add className --> createFunc to class map 541 (*classMap)[className] = createFunc; 542} 543 544// 545// 546Serializable * 547SerializableClass::createObject(Checkpoint *cp, const string §ion) 548{ 549 string className; 550 551 if (!cp->find(section, "type", className)) { 552 fatal("Serializable::create: no 'type' entry in section '%s'.\n", 553 section); 554 } 555 556 CreateFunc createFunc = (*classMap)[className]; 557 558 if (createFunc == NULL) { 559 fatal("Serializable::create: no create function for class '%s'.\n", 560 className); 561 } 562 563 Serializable *object = createFunc(cp, section); 564 565 assert(object != NULL); 566 567 return object; 568} 569 570 571Serializable * 572Serializable::create(Checkpoint *cp, const string §ion) 573{ 574 Serializable *object = SerializableClass::createObject(cp, section); 575 object->unserialize(cp, section); 576 return object; 577} 578 579 580const char *Checkpoint::baseFilename = "m5.cpt"; 581 582string Checkpoint::currentDirectory; 583 584string 585Checkpoint::setDir(const string &name) 586{ 587 // use csprintf to insert curTick() into directory name if it 588 // appears to have a format placeholder in it. 589 currentDirectory = (name.find("%") != string::npos) ? 590 csprintf(name, curTick()) : name; 591 if (currentDirectory[currentDirectory.size() - 1] != '/') 592 currentDirectory += "/"; 593 return currentDirectory; 594} 595 596string 597Checkpoint::dir() 598{ 599 return currentDirectory; 600} 601 602 603Checkpoint::Checkpoint(const string &cpt_dir) 604 : db(new IniFile), cptDir(setDir(cpt_dir)) 605{ 606 string filename = cptDir + "/" + Checkpoint::baseFilename; 607 if (!db->load(filename)) { 608 fatal("Can't load checkpoint file '%s'\n", filename); 609 } 610} 611 612Checkpoint::~Checkpoint() 613{ 614 delete db; 615} 616 617bool 618Checkpoint::find(const string §ion, const string &entry, string &value) 619{ 620 return db->find(section, entry, value); 621} 622 623 624bool 625Checkpoint::findObj(const string §ion, const string &entry, 626 SimObject *&value) 627{ 628 string path; 629 630 if (!db->find(section, entry, path)) 631 return false; 632 633 value = resolveSimObject(path); 634 return true; 635} 636 637 638bool 639Checkpoint::sectionExists(const string §ion) 640{ 641 return db->sectionExists(section); 642}
|