gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
serialize.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, 2018 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  *
14  * Copyright (c) 2002-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  * Authors: Nathan Binkert
41  * Erik Hallnor
42  * Steve Reinhardt
43  * Andreas Sandberg
44  */
45 
46 /* @file
47  * Serialization Interface Declarations
48  */
49 
50 #ifndef __SERIALIZE_HH__
51 #define __SERIALIZE_HH__
52 
53 
54 #include <algorithm>
55 #include <iostream>
56 #include <list>
57 #include <map>
58 #include <stack>
59 #include <set>
60 #include <vector>
61 
62 #include "base/bitunion.hh"
63 #include "base/logging.hh"
64 #include "base/str.hh"
65 
66 class IniFile;
67 class SimObject;
69 
70 typedef std::ostream CheckpointOut;
71 
73 {
74  private:
75 
77 
79 
80  public:
81  CheckpointIn(const std::string &cpt_dir, SimObjectResolver &resolver);
82  ~CheckpointIn();
83 
84  const std::string cptDir;
85 
86  bool find(const std::string &section, const std::string &entry,
87  std::string &value);
88 
89  bool findObj(const std::string &section, const std::string &entry,
90  SimObject *&value);
91 
92 
93  bool entryExists(const std::string &section, const std::string &entry);
94  bool sectionExists(const std::string &section);
95 
96  // The following static functions have to do with checkpoint
97  // creation rather than restoration. This class makes a handy
98  // namespace for them though. Currently no Checkpoint object is
99  // created on serialization (only unserialization) so we track the
100  // directory name as a global. It would be nice to change this
101  // someday
102 
103  private:
104  // current directory we're serializing into.
105  static std::string currentDirectory;
106 
107  public:
108  // Set the current directory. This function takes care of
109  // inserting curTick() if there's a '%d' in the argument, and
110  // appends a '/' if necessary. The final name is returned.
111  static std::string setDir(const std::string &base_name);
112 
113  // Export current checkpoint directory name so other objects can
114  // derive filenames from it (e.g., memory). The return value is
115  // guaranteed to end in '/' so filenames can be directly appended.
116  // This function is only valid while a checkpoint is being created.
117  static std::string dir();
118 
119  // Filename for base checkpoint file within directory.
120  static const char *baseFilename;
121 };
122 
154 {
155  protected:
174  public:
175  template<class CP>
176  ScopedCheckpointSection(CP &cp, const char *name) {
177  pushName(name);
178  nameOut(cp);
179  }
180 
181  template<class CP>
182  ScopedCheckpointSection(CP &cp, const std::string &name) {
183  pushName(name.c_str());
184  nameOut(cp);
185  }
186 
188 
189  ScopedCheckpointSection() = delete;
191  ScopedCheckpointSection &operator=(
192  const ScopedCheckpointSection &) = delete;
193  ScopedCheckpointSection &operator=(
194  ScopedCheckpointSection &&) = delete;
195 
196  private:
197  void pushName(const char *name);
198  void nameOut(CheckpointOut &cp);
199  void nameOut(CheckpointIn &cp) {};
200  };
201 
202  public:
203  Serializable();
204  virtual ~Serializable();
205 
213  virtual void serialize(CheckpointOut &cp) const = 0;
214 
222  virtual void unserialize(CheckpointIn &cp) = 0;
223 
235  void serializeSection(CheckpointOut &cp, const char *name) const;
236 
237  void serializeSection(CheckpointOut &cp, const std::string &name) const {
238  serializeSection(cp, name.c_str());
239  }
240 
251  void unserializeSection(CheckpointIn &cp, const char *name);
252 
253  void unserializeSection(CheckpointIn &cp, const std::string &name) {
254  unserializeSection(cp, name.c_str());
255  }
256 
258  static const std::string &currentSection();
259 
260  static int ckptCount;
261  static int ckptMaxCount;
262  static int ckptPrevCount;
263  static void serializeAll(const std::string &cpt_dir);
264  static void unserializeGlobals(CheckpointIn &cp);
265 
266  private:
267  static std::stack<std::string> path;
268 };
269 
270 //
271 // The base implementations use to_number for parsing and '<<' for
272 // displaying, suitable for integer types.
273 //
274 template <class T>
275 bool
276 parseParam(const std::string &s, T &value)
277 {
278  return to_number(s, value);
279 }
280 
281 template <class T>
282 void
283 showParam(CheckpointOut &os, const T &value)
284 {
285  os << value;
286 }
287 
288 template <class T>
289 bool
290 parseParam(const std::string &s, BitUnionType<T> &value)
291 {
292  // Zero initialize storage to avoid leaking an uninitialized value
294  auto res = to_number(s, storage);
295  value = storage;
296  return res;
297 }
298 
299 template <class T>
300 void
302 {
303  auto storage = static_cast<BitUnionBaseType<T>>(value);
304 
305  // For a BitUnion8, the storage type is an unsigned char.
306  // Since we want to serialize a number we need to cast to
307  // unsigned int
308  os << ((sizeof(storage) == 1) ?
309  static_cast<unsigned int>(storage) : storage);
310 }
311 
312 // Treat 8-bit ints (chars) as ints on output, not as chars
313 template <>
314 inline void
315 showParam(CheckpointOut &os, const char &value)
316 {
317  os << (int)value;
318 }
319 
320 template <>
321 inline void
322 showParam(CheckpointOut &os, const signed char &value)
323 {
324  os << (int)value;
325 }
326 
327 template <>
328 inline void
329 showParam(CheckpointOut &os, const unsigned char &value)
330 {
331  os << (unsigned int)value;
332 }
333 
334 template <>
335 inline bool
336 parseParam(const std::string &s, float &value)
337 {
338  return to_number(s, value);
339 }
340 
341 template <>
342 inline bool
343 parseParam(const std::string &s, double &value)
344 {
345  return to_number(s, value);
346 }
347 
348 template <>
349 inline bool
350 parseParam(const std::string &s, bool &value)
351 {
352  return to_bool(s, value);
353 }
354 
355 // Display bools as strings
356 template <>
357 inline void
358 showParam(CheckpointOut &os, const bool &value)
359 {
360  os << (value ? "true" : "false");
361 }
362 
363 // String requires no processing to speak of
364 template <>
365 inline bool
366 parseParam(const std::string &s, std::string &value)
367 {
368  value = s;
369  return true;
370 }
371 
372 template <class T>
373 void
374 paramOut(CheckpointOut &os, const std::string &name, const T &param)
375 {
376  os << name << "=";
377  showParam(os, param);
378  os << "\n";
379 }
380 
381 template <class T>
382 void
383 paramIn(CheckpointIn &cp, const std::string &name, T &param)
384 {
385  const std::string &section(Serializable::currentSection());
386  std::string str;
387  if (!cp.find(section, name, str) || !parseParam(str, param)) {
388  fatal("Can't unserialize '%s:%s'\n", section, name);
389  }
390 }
391 
392 template <class T>
393 bool
394 optParamIn(CheckpointIn &cp, const std::string &name,
395  T &param, bool warn = true)
396 {
397  const std::string &section(Serializable::currentSection());
398  std::string str;
399  if (!cp.find(section, name, str) || !parseParam(str, param)) {
400  if (warn)
401  warn("optional parameter %s:%s not present\n", section, name);
402  return false;
403  } else {
404  return true;
405  }
406 }
407 
408 template <class T>
409 void
410 arrayParamOut(CheckpointOut &os, const std::string &name,
411  const std::vector<T> &param)
412 {
413  typename std::vector<T>::size_type size = param.size();
414  os << name << "=";
415  if (size > 0)
416  showParam(os, param[0]);
417  for (typename std::vector<T>::size_type i = 1; i < size; ++i) {
418  os << " ";
419  showParam(os, param[i]);
420  }
421  os << "\n";
422 }
423 
424 template <class T>
425 void
426 arrayParamOut(CheckpointOut &os, const std::string &name,
427  const std::list<T> &param)
428 {
429  typename std::list<T>::const_iterator it = param.begin();
430 
431  os << name << "=";
432  if (param.size() > 0)
433  showParam(os, *it);
434  it++;
435  while (it != param.end()) {
436  os << " ";
437  showParam(os, *it);
438  it++;
439  }
440  os << "\n";
441 }
442 
443 template <class T>
444 void
445 arrayParamOut(CheckpointOut &os, const std::string &name,
446  const std::set<T> &param)
447 {
448  typename std::set<T>::const_iterator it = param.begin();
449 
450  os << name << "=";
451  if (param.size() > 0)
452  showParam(os, *it);
453  it++;
454  while (it != param.end()) {
455  os << " ";
456  showParam(os, *it);
457  it++;
458  }
459  os << "\n";
460 }
461 
462 template <class T>
463 void
464 arrayParamOut(CheckpointOut &os, const std::string &name,
465  const T *param, unsigned size)
466 {
467  os << name << "=";
468  if (size > 0)
469  showParam(os, param[0]);
470  for (unsigned i = 1; i < size; ++i) {
471  os << " ";
472  showParam(os, param[i]);
473  }
474  os << "\n";
475 }
476 
486 template <class T>
487 void
488 arrayParamIn(CheckpointIn &cp, const std::string &name,
489  T *param, unsigned size)
490 {
491  const std::string &section(Serializable::currentSection());
492  std::string str;
493  if (!cp.find(section, name, str)) {
494  fatal("Can't unserialize '%s:%s'\n", section, name);
495  }
496 
497  // code below stolen from VectorParam<T>::parse().
498  // it would be nice to unify these somehow...
499 
501 
502  tokenize(tokens, str, ' ');
503 
504  // Need this if we were doing a vector
505  // value.resize(tokens.size());
506 
507  fatal_if(tokens.size() != size,
508  "Array size mismatch on %s:%s (Got %u, expected %u)'\n",
509  section, name, tokens.size(), size);
510 
511  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
512  // need to parse into local variable to handle vector<bool>,
513  // for which operator[] returns a special reference class
514  // that's not the same as 'bool&', (since it's a packed
515  // vector)
516  T scalar_value;
517  if (!parseParam(tokens[i], scalar_value)) {
518  std::string err("could not parse \"");
519 
520  err += str;
521  err += "\"";
522 
523  fatal(err);
524  }
525 
526  // assign parsed value to vector
527  param[i] = scalar_value;
528  }
529 }
530 
531 template <class T>
532 void
533 arrayParamIn(CheckpointIn &cp, const std::string &name, std::vector<T> &param)
534 {
535  const std::string &section(Serializable::currentSection());
536  std::string str;
537  if (!cp.find(section, name, str)) {
538  fatal("Can't unserialize '%s:%s'\n", section, name);
539  }
540 
541  // code below stolen from VectorParam<T>::parse().
542  // it would be nice to unify these somehow...
543 
545 
546  tokenize(tokens, str, ' ');
547 
548  // Need this if we were doing a vector
549  // value.resize(tokens.size());
550 
551  param.resize(tokens.size());
552 
553  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
554  // need to parse into local variable to handle vector<bool>,
555  // for which operator[] returns a special reference class
556  // that's not the same as 'bool&', (since it's a packed
557  // vector)
558  T scalar_value;
559  if (!parseParam(tokens[i], scalar_value)) {
560  std::string err("could not parse \"");
561 
562  err += str;
563  err += "\"";
564 
565  fatal(err);
566  }
567 
568  // assign parsed value to vector
569  param[i] = scalar_value;
570  }
571 }
572 
573 template <class T>
574 void
575 arrayParamIn(CheckpointIn &cp, const std::string &name, std::list<T> &param)
576 {
577  const std::string &section(Serializable::currentSection());
578  std::string str;
579  if (!cp.find(section, name, str)) {
580  fatal("Can't unserialize '%s:%s'\n", section, name);
581  }
582  param.clear();
583 
585  tokenize(tokens, str, ' ');
586 
587  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
588  T scalar_value;
589  if (!parseParam(tokens[i], scalar_value)) {
590  std::string err("could not parse \"");
591 
592  err += str;
593  err += "\"";
594 
595  fatal(err);
596  }
597 
598  // assign parsed value to vector
599  param.push_back(scalar_value);
600  }
601 }
602 
603 template <class T>
604 void
605 arrayParamIn(CheckpointIn &cp, const std::string &name, std::set<T> &param)
606 {
607  const std::string &section(Serializable::currentSection());
608  std::string str;
609  if (!cp.find(section, name, str)) {
610  fatal("Can't unserialize '%s:%s'\n", section, name);
611  }
612  param.clear();
613 
615  tokenize(tokens, str, ' ');
616 
617  for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
618  T scalar_value;
619  if (!parseParam(tokens[i], scalar_value)) {
620  std::string err("could not parse \"");
621 
622  err += str;
623  err += "\"";
624 
625  fatal(err);
626  }
627 
628  // assign parsed value to vector
629  param.insert(scalar_value);
630  }
631 }
632 
633 void
634 debug_serialize(const std::string &cpt_dir);
635 
636 void
637 objParamIn(CheckpointIn &cp, const std::string &name, SimObject * &param);
638 
639 //
640 // These macros are streamlined to use in serialize/unserialize
641 // functions. It's assumed that serialize() has a parameter 'os' for
642 // the ostream, and unserialize() has parameters 'cp' and 'section'.
643 #define SERIALIZE_SCALAR(scalar) paramOut(cp, #scalar, scalar)
644 
645 #define UNSERIALIZE_SCALAR(scalar) paramIn(cp, #scalar, scalar)
646 #define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, #scalar, scalar)
647 
648 // ENUMs are like SCALARs, but we cast them to ints on the way out
649 #define SERIALIZE_ENUM(scalar) paramOut(cp, #scalar, (int)scalar)
650 
651 #define UNSERIALIZE_ENUM(scalar) \
652  do { \
653  int tmp; \
654  paramIn(cp, #scalar, tmp); \
655  scalar = static_cast<decltype(scalar)>(tmp); \
656  } while (0)
657 
658 #define SERIALIZE_ARRAY(member, size) \
659  arrayParamOut(cp, #member, member, size)
660 
661 #define UNSERIALIZE_ARRAY(member, size) \
662  arrayParamIn(cp, #member, member, size)
663 
664 #define SERIALIZE_CONTAINER(member) \
665  arrayParamOut(cp, #member, member)
666 
667 #define UNSERIALIZE_CONTAINER(member) \
668  arrayParamIn(cp, #member, member)
669 
670 #define SERIALIZE_EVENT(event) event.serializeSection(cp, #event);
671 
672 #define UNSERIALIZE_EVENT(event) \
673  do { \
674  event.unserializeSection(cp, #event); \
675  eventQueue()->checkpointReschedule(&event); \
676  } while (0)
677 
678 #define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj)
679 #define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj)
680 
681 #define SERIALIZE_OBJPTR(objptr) paramOut(cp, #objptr, (objptr)->name())
682 
683 #define UNSERIALIZE_OBJPTR(objptr) \
684  do { \
685  SimObject *sptr; \
686  objParamIn(cp, #objptr, sptr); \
687  objptr = dynamic_cast<decltype(objptr)>(sptr); \
688  } while (0)
689 
690 #endif // __SERIALIZE_HH__
const std::string cptDir
Definition: serialize.hh:84
void showParam(CheckpointOut &os, const T &value)
Definition: serialize.hh:283
bool to_bool(const std::string &value, bool &retval)
Turn a string representation of a boolean into a boolean value.
Definition: str.hh:189
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:175
static std::string dir()
Definition: serialize.cc:268
const std::string & name()
Definition: trace.cc:54
Bitfield< 7 > i
static std::stack< std::string > path
Definition: serialize.hh:267
SimObjectResolver & objNameResolver
Definition: serialize.hh:78
static std::string currentDirectory
Definition: serialize.hh:105
bool parseParam(const std::string &s, T &value)
Definition: serialize.hh:276
static int ckptPrevCount
Definition: serialize.hh:262
static int ckptCount
Definition: serialize.hh:260
Definition: cprintf.cc:42
Base class to wrap object resolving functionality.
Definition: sim_object.hh:242
Bitfield< 17 > os
Definition: misc.hh:805
STL vector class.
Definition: stl.hh:40
ScopedCheckpointSection(CP &cp, const std::string &name)
Definition: serialize.hh:182
void serializeSection(CheckpointOut &cp, const std::string &name) const
Definition: serialize.hh:237
void unserializeSection(CheckpointIn &cp, const std::string &name)
Definition: serialize.hh:253
bool find(const std::string &section, const std::string &entry, std::string &value)
Definition: serialize.cc:294
void paramOut(CheckpointOut &os, const std::string &name, const T &param)
Definition: serialize.hh:374
Bitfield< 4 > s
void debug_serialize(const std::string &cpt_dir)
void objParamIn(CheckpointIn &cp, const std::string &name, SimObject *&param)
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:203
STL list class.
Definition: stl.hh:54
bool to_number(const std::string &value, VecPredRegContainer< NumBits, Packed > &p)
Helper functions used for serialization/de-serialization.
Basic support for object serialization.
Definition: serialize.hh:153
std::ostream CheckpointOut
Definition: serialize.hh:68
bool sectionExists(const std::string &section)
Definition: serialize.cc:313
typename BitfieldBackend::BitUnionBaseType< T >::Type BitUnionBaseType
Definition: bitunion.hh:416
static int ckptMaxCount
Definition: serialize.hh:261
static const std::string & currentSection()
Get the fully-qualified name of the active section.
Definition: serialize.cc:244
void nameOut(CheckpointIn &cp)
Definition: serialize.hh:199
void tokenize(vector< string > &v, const string &s, char token, bool ignore)
Definition: str.cc:69
bool entryExists(const std::string &section, const std::string &entry)
Definition: serialize.cc:288
IniFile * db
Definition: serialize.hh:76
void unserialize(ThreadContext &tc, CheckpointIn &cp)
bool findObj(const std::string &section, const std::string &entry, SimObject *&value)
Definition: serialize.cc:300
#define warn(...)
Definition: logging.hh:212
ScopedCheckpointSection(CP &cp, const char *name)
Definition: serialize.hh:176
Scoped checkpoint section helper class.
Definition: serialize.hh:173
bool optParamIn(CheckpointIn &cp, const std::string &name, T &param, bool warn=true)
Definition: serialize.hh:394
Abstract superclass for simulation objects.
Definition: sim_object.hh:96
This class represents the contents of a ".ini" file.
Definition: inifile.hh:54
static const char * baseFilename
Definition: serialize.hh:120
CheckpointIn(const std::string &cpt_dir, SimObjectResolver &resolver)
Definition: serialize.cc:273
void arrayParamOut(CheckpointOut &os, const std::string &name, const std::vector< T > &param)
Definition: serialize.hh:410
void arrayParamIn(CheckpointIn &cp, const std::string &name, T *param, unsigned size)
Extract values stored in the checkpoint, and assign them to the provided array container.
Definition: serialize.hh:488
void paramIn(CheckpointIn &cp, const std::string &name, T &param)
Definition: serialize.hh:383
static std::string setDir(const std::string &base_name)
Definition: serialize.cc:256

Generated on Fri Feb 28 2020 16:27:03 for gem5 by doxygen 1.8.13