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