serialize.hh (13414:1b5387dccec3) serialize.hh (13415:dfba7ea400e2)
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
66class IniFile;
67class SimObject;
68class SimObjectResolver;
69
70typedef std::ostream CheckpointOut;
71
72class CheckpointIn
73{
74 private:
75
76 IniFile *db;
77
78 SimObjectResolver &objNameResolver;
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
123/**
124 * Basic support for object serialization.
125 *
126 * Objects that support serialization should derive from this
127 * class. Such objects can largely be divided into two categories: 1)
128 * True SimObjects (deriving from SimObject), and 2) child objects
129 * (non-SimObjects).
130 *
131 * SimObjects are serialized automatically into their own sections
132 * automatically by the SimObject base class (see
133 * SimObject::serializeAll().
134 *
135 * SimObjects can contain other serializable objects that are not
136 * SimObjects. Much like normal serialized members are not serialized
137 * automatically, these objects will not be serialized automatically
138 * and it is expected that the objects owning such serializable
139 * objects call the required serialization/unserialization methods on
140 * child objects. The preferred method to serialize a child object is
141 * to call serializeSection() on the child, which serializes the
142 * object into a new subsection in the current section. Another option
143 * is to call serialize() directly, which serializes the object into
144 * the current section. The latter is not recommended as it can lead
145 * to naming clashes between objects.
146 *
147 * @note Many objects that support serialization need to be put in a
148 * consistent state when serialization takes place. We refer to the
149 * action of forcing an object into a consistent state as
150 * 'draining'. Objects that need draining inherit from Drainable. See
151 * Drainable for more information.
152 */
153class Serializable
154{
155 protected:
156 /**
157 * Scoped checkpoint section helper class
158 *
159 * This helper class creates a section within a checkpoint without
160 * the need for a separate serializeable object. It is mainly used
161 * within the Serializable class when serializing or unserializing
162 * section (see serializeSection() and unserializeSection()). It
163 * can also be used to maintain backwards compatibility in
164 * existing code that serializes structs that are not inheriting
165 * from Serializable into subsections.
166 *
167 * When the class is instantiated, it appends a name to the active
168 * path in a checkpoint. The old path is later restored when the
169 * instance is destroyed. For example, serializeSection() could be
170 * implemented by instantiating a ScopedCheckpointSection and then
171 * calling serialize() on an object.
172 */
173 class ScopedCheckpointSection {
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
187 ~ScopedCheckpointSection();
188
189 ScopedCheckpointSection() = delete;
190 ScopedCheckpointSection(const 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
206 /**
207 * Serialize an object
208 *
209 * Output an object's state into the current checkpoint section.
210 *
211 * @param cp Checkpoint state
212 */
213 virtual void serialize(CheckpointOut &cp) const = 0;
214
215 /**
216 * Unserialize an object
217 *
218 * Read an object's state from the current checkpoint section.
219 *
220 * @param cp Checkpoint state
221 */
222 virtual void unserialize(CheckpointIn &cp) = 0;
223
224 /**
225 * Serialize an object into a new section
226 *
227 * This method creates a new section in a checkpoint and calls
228 * serialize() to serialize the current object into that
229 * section. The name of the section is appended to the current
230 * checkpoint path.
231 *
232 * @param cp Checkpoint state
233 * @param name Name to append to the active path
234 */
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
241 /**
242 * Unserialize an a child object
243 *
244 * This method loads a child object from a checkpoint. The object
245 * name is appended to the active path to form a fully qualified
246 * section name and unserialize() is called.
247 *
248 * @param cp Checkpoint state
249 * @param name Name to append to the active path
250 */
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
257 /** Get the fully-qualified name of the active section */
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//
274template <class T>
275bool
276parseParam(const std::string &s, T &value)
277{
278 return to_number(s, value);
279}
280
281template <class T>
282void
283showParam(CheckpointOut &os, const T &value)
284{
285 os << value;
286}
287
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
66class IniFile;
67class SimObject;
68class SimObjectResolver;
69
70typedef std::ostream CheckpointOut;
71
72class CheckpointIn
73{
74 private:
75
76 IniFile *db;
77
78 SimObjectResolver &objNameResolver;
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
123/**
124 * Basic support for object serialization.
125 *
126 * Objects that support serialization should derive from this
127 * class. Such objects can largely be divided into two categories: 1)
128 * True SimObjects (deriving from SimObject), and 2) child objects
129 * (non-SimObjects).
130 *
131 * SimObjects are serialized automatically into their own sections
132 * automatically by the SimObject base class (see
133 * SimObject::serializeAll().
134 *
135 * SimObjects can contain other serializable objects that are not
136 * SimObjects. Much like normal serialized members are not serialized
137 * automatically, these objects will not be serialized automatically
138 * and it is expected that the objects owning such serializable
139 * objects call the required serialization/unserialization methods on
140 * child objects. The preferred method to serialize a child object is
141 * to call serializeSection() on the child, which serializes the
142 * object into a new subsection in the current section. Another option
143 * is to call serialize() directly, which serializes the object into
144 * the current section. The latter is not recommended as it can lead
145 * to naming clashes between objects.
146 *
147 * @note Many objects that support serialization need to be put in a
148 * consistent state when serialization takes place. We refer to the
149 * action of forcing an object into a consistent state as
150 * 'draining'. Objects that need draining inherit from Drainable. See
151 * Drainable for more information.
152 */
153class Serializable
154{
155 protected:
156 /**
157 * Scoped checkpoint section helper class
158 *
159 * This helper class creates a section within a checkpoint without
160 * the need for a separate serializeable object. It is mainly used
161 * within the Serializable class when serializing or unserializing
162 * section (see serializeSection() and unserializeSection()). It
163 * can also be used to maintain backwards compatibility in
164 * existing code that serializes structs that are not inheriting
165 * from Serializable into subsections.
166 *
167 * When the class is instantiated, it appends a name to the active
168 * path in a checkpoint. The old path is later restored when the
169 * instance is destroyed. For example, serializeSection() could be
170 * implemented by instantiating a ScopedCheckpointSection and then
171 * calling serialize() on an object.
172 */
173 class ScopedCheckpointSection {
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
187 ~ScopedCheckpointSection();
188
189 ScopedCheckpointSection() = delete;
190 ScopedCheckpointSection(const 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
206 /**
207 * Serialize an object
208 *
209 * Output an object's state into the current checkpoint section.
210 *
211 * @param cp Checkpoint state
212 */
213 virtual void serialize(CheckpointOut &cp) const = 0;
214
215 /**
216 * Unserialize an object
217 *
218 * Read an object's state from the current checkpoint section.
219 *
220 * @param cp Checkpoint state
221 */
222 virtual void unserialize(CheckpointIn &cp) = 0;
223
224 /**
225 * Serialize an object into a new section
226 *
227 * This method creates a new section in a checkpoint and calls
228 * serialize() to serialize the current object into that
229 * section. The name of the section is appended to the current
230 * checkpoint path.
231 *
232 * @param cp Checkpoint state
233 * @param name Name to append to the active path
234 */
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
241 /**
242 * Unserialize an a child object
243 *
244 * This method loads a child object from a checkpoint. The object
245 * name is appended to the active path to form a fully qualified
246 * section name and unserialize() is called.
247 *
248 * @param cp Checkpoint state
249 * @param name Name to append to the active path
250 */
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
257 /** Get the fully-qualified name of the active section */
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//
274template <class T>
275bool
276parseParam(const std::string &s, T &value)
277{
278 return to_number(s, value);
279}
280
281template <class T>
282void
283showParam(CheckpointOut &os, const T &value)
284{
285 os << value;
286}
287
288template <class T>
289bool
290parseParam(const std::string &s, BitUnionType<T> &value)
291{
292 auto storage = static_cast<BitUnionBaseType<T>>(value);
293 auto res = to_number(s, storage);
294 value = storage;
295 return res;
296}
297
298template <class T>
299void
300showParam(CheckpointOut &os, const BitUnionType<T> &value)
301{
302 auto storage = static_cast<BitUnionBaseType<T>>(value);
303
304 // For a BitUnion8, the storage type is an unsigned char.
305 // Since we want to serialize a number we need to cast to
306 // unsigned int
307 os << ((sizeof(storage) == 1) ?
308 static_cast<unsigned int>(storage) : storage);
309}
310
288// Treat 8-bit ints (chars) as ints on output, not as chars
289template <>
290inline void
291showParam(CheckpointOut &os, const char &value)
292{
293 os << (int)value;
294}
295
296template <>
297inline void
298showParam(CheckpointOut &os, const signed char &value)
299{
300 os << (int)value;
301}
302
303template <>
304inline void
305showParam(CheckpointOut &os, const unsigned char &value)
306{
307 os << (unsigned int)value;
308}
309
310template <>
311inline bool
312parseParam(const std::string &s, float &value)
313{
314 return to_number(s, value);
315}
316
317template <>
318inline bool
319parseParam(const std::string &s, double &value)
320{
321 return to_number(s, value);
322}
323
324template <>
325inline bool
326parseParam(const std::string &s, bool &value)
327{
328 return to_bool(s, value);
329}
330
331// Display bools as strings
332template <>
333inline void
334showParam(CheckpointOut &os, const bool &value)
335{
336 os << (value ? "true" : "false");
337}
338
339// String requires no processing to speak of
340template <>
341inline bool
342parseParam(const std::string &s, std::string &value)
343{
344 value = s;
345 return true;
346}
347
348template <class T>
349void
350paramOut(CheckpointOut &os, const std::string &name, const T &param)
351{
352 os << name << "=";
353 showParam(os, param);
354 os << "\n";
355}
356
311// Treat 8-bit ints (chars) as ints on output, not as chars
312template <>
313inline void
314showParam(CheckpointOut &os, const char &value)
315{
316 os << (int)value;
317}
318
319template <>
320inline void
321showParam(CheckpointOut &os, const signed char &value)
322{
323 os << (int)value;
324}
325
326template <>
327inline void
328showParam(CheckpointOut &os, const unsigned char &value)
329{
330 os << (unsigned int)value;
331}
332
333template <>
334inline bool
335parseParam(const std::string &s, float &value)
336{
337 return to_number(s, value);
338}
339
340template <>
341inline bool
342parseParam(const std::string &s, double &value)
343{
344 return to_number(s, value);
345}
346
347template <>
348inline bool
349parseParam(const std::string &s, bool &value)
350{
351 return to_bool(s, value);
352}
353
354// Display bools as strings
355template <>
356inline void
357showParam(CheckpointOut &os, const bool &value)
358{
359 os << (value ? "true" : "false");
360}
361
362// String requires no processing to speak of
363template <>
364inline bool
365parseParam(const std::string &s, std::string &value)
366{
367 value = s;
368 return true;
369}
370
371template <class T>
372void
373paramOut(CheckpointOut &os, const std::string &name, const T &param)
374{
375 os << name << "=";
376 showParam(os, param);
377 os << "\n";
378}
379
357template <typename T>
358void
359paramOut(CheckpointOut &cp, const std::string &name, const BitUnionType<T> &p)
360{
361 paramOut(cp, name, static_cast<BitUnionBaseType<T> >(p));
362}
363
364template <class T>
365void
366paramIn(CheckpointIn &cp, const std::string &name, T &param)
367{
368 const std::string &section(Serializable::currentSection());
369 std::string str;
370 if (!cp.find(section, name, str) || !parseParam(str, param)) {
371 fatal("Can't unserialize '%s:%s'\n", section, name);
372 }
373}
374
380template <class T>
381void
382paramIn(CheckpointIn &cp, const std::string &name, T &param)
383{
384 const std::string &section(Serializable::currentSection());
385 std::string str;
386 if (!cp.find(section, name, str) || !parseParam(str, param)) {
387 fatal("Can't unserialize '%s:%s'\n", section, name);
388 }
389}
390
375template <typename T>
376void
377paramIn(CheckpointIn &cp, const std::string &name, BitUnionType<T> &p)
378{
379 BitUnionBaseType<T> b;
380 paramIn(cp, name, b);
381 p = b;
382}
383
384template <class T>
385bool
386optParamIn(CheckpointIn &cp, const std::string &name,
387 T &param, bool warn = true)
388{
389 const std::string &section(Serializable::currentSection());
390 std::string str;
391 if (!cp.find(section, name, str) || !parseParam(str, param)) {
392 if (warn)
393 warn("optional parameter %s:%s not present\n", section, name);
394 return false;
395 } else {
396 return true;
397 }
398}
399
391template <class T>
392bool
393optParamIn(CheckpointIn &cp, const std::string &name,
394 T &param, bool warn = true)
395{
396 const std::string &section(Serializable::currentSection());
397 std::string str;
398 if (!cp.find(section, name, str) || !parseParam(str, param)) {
399 if (warn)
400 warn("optional parameter %s:%s not present\n", section, name);
401 return false;
402 } else {
403 return true;
404 }
405}
406
400template <typename T>
401bool
402optParamIn(CheckpointIn &cp, const std::string &name,
403 BitUnionType<T> &p, bool warn = true)
404{
405 BitUnionBaseType<T> b;
406 if (optParamIn(cp, name, b, warn)) {
407 p = b;
408 return true;
409 } else {
410 return false;
411 }
412}
413
414template <class T>
415void
416arrayParamOut(CheckpointOut &os, const std::string &name,
417 const std::vector<T> &param)
418{
419 typename std::vector<T>::size_type size = param.size();
420 os << name << "=";
421 if (size > 0)
422 showParam(os, param[0]);
423 for (typename std::vector<T>::size_type i = 1; i < size; ++i) {
424 os << " ";
425 showParam(os, param[i]);
426 }
427 os << "\n";
428}
429
430template <class T>
431void
432arrayParamOut(CheckpointOut &os, const std::string &name,
433 const std::list<T> &param)
434{
435 typename std::list<T>::const_iterator it = param.begin();
436
437 os << name << "=";
438 if (param.size() > 0)
439 showParam(os, *it);
440 it++;
441 while (it != param.end()) {
442 os << " ";
443 showParam(os, *it);
444 it++;
445 }
446 os << "\n";
447}
448
449template <class T>
450void
451arrayParamOut(CheckpointOut &os, const std::string &name,
452 const std::set<T> &param)
453{
454 typename std::set<T>::const_iterator it = param.begin();
455
456 os << name << "=";
457 if (param.size() > 0)
458 showParam(os, *it);
459 it++;
460 while (it != param.end()) {
461 os << " ";
462 showParam(os, *it);
463 it++;
464 }
465 os << "\n";
466}
467
468template <class T>
469void
470arrayParamOut(CheckpointOut &os, const std::string &name,
471 const T *param, unsigned size)
472{
473 os << name << "=";
474 if (size > 0)
475 showParam(os, param[0]);
476 for (unsigned i = 1; i < size; ++i) {
477 os << " ";
478 showParam(os, param[i]);
479 }
480 os << "\n";
481}
482
483
484template <class T>
485void
486arrayParamIn(CheckpointIn &cp, const std::string &name,
487 T *param, unsigned size)
488{
489 const std::string &section(Serializable::currentSection());
490 std::string str;
491 if (!cp.find(section, name, str)) {
492 fatal("Can't unserialize '%s:%s'\n", section, name);
493 }
494
495 // code below stolen from VectorParam<T>::parse().
496 // it would be nice to unify these somehow...
497
498 std::vector<std::string> tokens;
499
500 tokenize(tokens, str, ' ');
501
502 // Need this if we were doing a vector
503 // value.resize(tokens.size());
504
505 if (tokens.size() != size) {
506 fatal("Array size mismatch on %s:%s'\n", section, name);
507 }
508
509 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
510 // need to parse into local variable to handle vector<bool>,
511 // for which operator[] returns a special reference class
512 // that's not the same as 'bool&', (since it's a packed
513 // vector)
514 T scalar_value;
515 if (!parseParam(tokens[i], scalar_value)) {
516 std::string err("could not parse \"");
517
518 err += str;
519 err += "\"";
520
521 fatal(err);
522 }
523
524 // assign parsed value to vector
525 param[i] = scalar_value;
526 }
527}
528
529template <class T>
530void
531arrayParamIn(CheckpointIn &cp, const std::string &name, std::vector<T> &param)
532{
533 const std::string &section(Serializable::currentSection());
534 std::string str;
535 if (!cp.find(section, name, str)) {
536 fatal("Can't unserialize '%s:%s'\n", section, name);
537 }
538
539 // code below stolen from VectorParam<T>::parse().
540 // it would be nice to unify these somehow...
541
542 std::vector<std::string> tokens;
543
544 tokenize(tokens, str, ' ');
545
546 // Need this if we were doing a vector
547 // value.resize(tokens.size());
548
549 param.resize(tokens.size());
550
551 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
552 // need to parse into local variable to handle vector<bool>,
553 // for which operator[] returns a special reference class
554 // that's not the same as 'bool&', (since it's a packed
555 // vector)
556 T scalar_value;
557 if (!parseParam(tokens[i], scalar_value)) {
558 std::string err("could not parse \"");
559
560 err += str;
561 err += "\"";
562
563 fatal(err);
564 }
565
566 // assign parsed value to vector
567 param[i] = scalar_value;
568 }
569}
570
571template <class T>
572void
573arrayParamIn(CheckpointIn &cp, const std::string &name, std::list<T> &param)
574{
575 const std::string &section(Serializable::currentSection());
576 std::string str;
577 if (!cp.find(section, name, str)) {
578 fatal("Can't unserialize '%s:%s'\n", section, name);
579 }
580 param.clear();
581
582 std::vector<std::string> tokens;
583 tokenize(tokens, str, ' ');
584
585 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
586 T scalar_value;
587 if (!parseParam(tokens[i], scalar_value)) {
588 std::string err("could not parse \"");
589
590 err += str;
591 err += "\"";
592
593 fatal(err);
594 }
595
596 // assign parsed value to vector
597 param.push_back(scalar_value);
598 }
599}
600
601template <class T>
602void
603arrayParamIn(CheckpointIn &cp, const std::string &name, std::set<T> &param)
604{
605 const std::string &section(Serializable::currentSection());
606 std::string str;
607 if (!cp.find(section, name, str)) {
608 fatal("Can't unserialize '%s:%s'\n", section, name);
609 }
610 param.clear();
611
612 std::vector<std::string> tokens;
613 tokenize(tokens, str, ' ');
614
615 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
616 T scalar_value;
617 if (!parseParam(tokens[i], scalar_value)) {
618 std::string err("could not parse \"");
619
620 err += str;
621 err += "\"";
622
623 fatal(err);
624 }
625
626 // assign parsed value to vector
627 param.insert(scalar_value);
628 }
629}
630
407template <class T>
408void
409arrayParamOut(CheckpointOut &os, const std::string &name,
410 const std::vector<T> &param)
411{
412 typename std::vector<T>::size_type size = param.size();
413 os << name << "=";
414 if (size > 0)
415 showParam(os, param[0]);
416 for (typename std::vector<T>::size_type i = 1; i < size; ++i) {
417 os << " ";
418 showParam(os, param[i]);
419 }
420 os << "\n";
421}
422
423template <class T>
424void
425arrayParamOut(CheckpointOut &os, const std::string &name,
426 const std::list<T> &param)
427{
428 typename std::list<T>::const_iterator it = param.begin();
429
430 os << name << "=";
431 if (param.size() > 0)
432 showParam(os, *it);
433 it++;
434 while (it != param.end()) {
435 os << " ";
436 showParam(os, *it);
437 it++;
438 }
439 os << "\n";
440}
441
442template <class T>
443void
444arrayParamOut(CheckpointOut &os, const std::string &name,
445 const std::set<T> &param)
446{
447 typename std::set<T>::const_iterator it = param.begin();
448
449 os << name << "=";
450 if (param.size() > 0)
451 showParam(os, *it);
452 it++;
453 while (it != param.end()) {
454 os << " ";
455 showParam(os, *it);
456 it++;
457 }
458 os << "\n";
459}
460
461template <class T>
462void
463arrayParamOut(CheckpointOut &os, const std::string &name,
464 const T *param, unsigned size)
465{
466 os << name << "=";
467 if (size > 0)
468 showParam(os, param[0]);
469 for (unsigned i = 1; i < size; ++i) {
470 os << " ";
471 showParam(os, param[i]);
472 }
473 os << "\n";
474}
475
476
477template <class T>
478void
479arrayParamIn(CheckpointIn &cp, const std::string &name,
480 T *param, unsigned size)
481{
482 const std::string &section(Serializable::currentSection());
483 std::string str;
484 if (!cp.find(section, name, str)) {
485 fatal("Can't unserialize '%s:%s'\n", section, name);
486 }
487
488 // code below stolen from VectorParam<T>::parse().
489 // it would be nice to unify these somehow...
490
491 std::vector<std::string> tokens;
492
493 tokenize(tokens, str, ' ');
494
495 // Need this if we were doing a vector
496 // value.resize(tokens.size());
497
498 if (tokens.size() != size) {
499 fatal("Array size mismatch on %s:%s'\n", section, name);
500 }
501
502 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
503 // need to parse into local variable to handle vector<bool>,
504 // for which operator[] returns a special reference class
505 // that's not the same as 'bool&', (since it's a packed
506 // vector)
507 T scalar_value;
508 if (!parseParam(tokens[i], scalar_value)) {
509 std::string err("could not parse \"");
510
511 err += str;
512 err += "\"";
513
514 fatal(err);
515 }
516
517 // assign parsed value to vector
518 param[i] = scalar_value;
519 }
520}
521
522template <class T>
523void
524arrayParamIn(CheckpointIn &cp, const std::string &name, std::vector<T> &param)
525{
526 const std::string &section(Serializable::currentSection());
527 std::string str;
528 if (!cp.find(section, name, str)) {
529 fatal("Can't unserialize '%s:%s'\n", section, name);
530 }
531
532 // code below stolen from VectorParam<T>::parse().
533 // it would be nice to unify these somehow...
534
535 std::vector<std::string> tokens;
536
537 tokenize(tokens, str, ' ');
538
539 // Need this if we were doing a vector
540 // value.resize(tokens.size());
541
542 param.resize(tokens.size());
543
544 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
545 // need to parse into local variable to handle vector<bool>,
546 // for which operator[] returns a special reference class
547 // that's not the same as 'bool&', (since it's a packed
548 // vector)
549 T scalar_value;
550 if (!parseParam(tokens[i], scalar_value)) {
551 std::string err("could not parse \"");
552
553 err += str;
554 err += "\"";
555
556 fatal(err);
557 }
558
559 // assign parsed value to vector
560 param[i] = scalar_value;
561 }
562}
563
564template <class T>
565void
566arrayParamIn(CheckpointIn &cp, const std::string &name, std::list<T> &param)
567{
568 const std::string &section(Serializable::currentSection());
569 std::string str;
570 if (!cp.find(section, name, str)) {
571 fatal("Can't unserialize '%s:%s'\n", section, name);
572 }
573 param.clear();
574
575 std::vector<std::string> tokens;
576 tokenize(tokens, str, ' ');
577
578 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
579 T scalar_value;
580 if (!parseParam(tokens[i], scalar_value)) {
581 std::string err("could not parse \"");
582
583 err += str;
584 err += "\"";
585
586 fatal(err);
587 }
588
589 // assign parsed value to vector
590 param.push_back(scalar_value);
591 }
592}
593
594template <class T>
595void
596arrayParamIn(CheckpointIn &cp, const std::string &name, std::set<T> &param)
597{
598 const std::string &section(Serializable::currentSection());
599 std::string str;
600 if (!cp.find(section, name, str)) {
601 fatal("Can't unserialize '%s:%s'\n", section, name);
602 }
603 param.clear();
604
605 std::vector<std::string> tokens;
606 tokenize(tokens, str, ' ');
607
608 for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
609 T scalar_value;
610 if (!parseParam(tokens[i], scalar_value)) {
611 std::string err("could not parse \"");
612
613 err += str;
614 err += "\"";
615
616 fatal(err);
617 }
618
619 // assign parsed value to vector
620 param.insert(scalar_value);
621 }
622}
623
631template <class T>
632static void
633arrayParamOut(CheckpointOut &cp, const std::string &name,
634 const BitUnionType<T> *param, unsigned size)
635{
636 // We copy the array into a vector. This is needed since we cannot
637 // directly typecast a pointer to BitUnionType<T> into a pointer
638 // of BitUnionBaseType<T> but we can typecast BitUnionType<T>
639 // to BitUnionBaseType<T> since we overloaded the typecast operator
640 std::vector<BitUnionBaseType<T>> bitunion_vec(param, param + size);
641
642 arrayParamOut(cp, name, bitunion_vec);
643}
644
645template <class T>
646static void
647arrayParamIn(CheckpointIn &cp, const std::string &name,
648 BitUnionType<T> *param, unsigned size)
649{
650 std::vector<BitUnionBaseType<T>> bitunion_vec(size);
651
652 arrayParamIn(cp, name, bitunion_vec);
653 std::copy(bitunion_vec.begin(), bitunion_vec.end(), param);
654}
655
656void
657debug_serialize(const std::string &cpt_dir);
658
659void
660objParamIn(CheckpointIn &cp, const std::string &name, SimObject * &param);
661
662//
663// These macros are streamlined to use in serialize/unserialize
664// functions. It's assumed that serialize() has a parameter 'os' for
665// the ostream, and unserialize() has parameters 'cp' and 'section'.
666#define SERIALIZE_SCALAR(scalar) paramOut(cp, #scalar, scalar)
667
668#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, #scalar, scalar)
669#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, #scalar, scalar)
670
671// ENUMs are like SCALARs, but we cast them to ints on the way out
672#define SERIALIZE_ENUM(scalar) paramOut(cp, #scalar, (int)scalar)
673
674#define UNSERIALIZE_ENUM(scalar) \
675 do { \
676 int tmp; \
677 paramIn(cp, #scalar, tmp); \
678 scalar = static_cast<decltype(scalar)>(tmp); \
679 } while (0)
680
681#define SERIALIZE_ARRAY(member, size) \
682 arrayParamOut(cp, #member, member, size)
683
684#define UNSERIALIZE_ARRAY(member, size) \
685 arrayParamIn(cp, #member, member, size)
686
687#define SERIALIZE_CONTAINER(member) \
688 arrayParamOut(cp, #member, member)
689
690#define UNSERIALIZE_CONTAINER(member) \
691 arrayParamIn(cp, #member, member)
692
693#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event);
694
695#define UNSERIALIZE_EVENT(event) \
696 do { \
697 event.unserializeSection(cp, #event); \
698 eventQueue()->checkpointReschedule(&event); \
699 } while (0)
700
701#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj)
702#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj)
703
704#define SERIALIZE_OBJPTR(objptr) paramOut(cp, #objptr, (objptr)->name())
705
706#define UNSERIALIZE_OBJPTR(objptr) \
707 do { \
708 SimObject *sptr; \
709 objParamIn(cp, #objptr, sptr); \
710 objptr = dynamic_cast<decltype(objptr)>(sptr); \
711 } while (0)
712
713#endif // __SERIALIZE_HH__
624void
625debug_serialize(const std::string &cpt_dir);
626
627void
628objParamIn(CheckpointIn &cp, const std::string &name, SimObject * &param);
629
630//
631// These macros are streamlined to use in serialize/unserialize
632// functions. It's assumed that serialize() has a parameter 'os' for
633// the ostream, and unserialize() has parameters 'cp' and 'section'.
634#define SERIALIZE_SCALAR(scalar) paramOut(cp, #scalar, scalar)
635
636#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, #scalar, scalar)
637#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, #scalar, scalar)
638
639// ENUMs are like SCALARs, but we cast them to ints on the way out
640#define SERIALIZE_ENUM(scalar) paramOut(cp, #scalar, (int)scalar)
641
642#define UNSERIALIZE_ENUM(scalar) \
643 do { \
644 int tmp; \
645 paramIn(cp, #scalar, tmp); \
646 scalar = static_cast<decltype(scalar)>(tmp); \
647 } while (0)
648
649#define SERIALIZE_ARRAY(member, size) \
650 arrayParamOut(cp, #member, member, size)
651
652#define UNSERIALIZE_ARRAY(member, size) \
653 arrayParamIn(cp, #member, member, size)
654
655#define SERIALIZE_CONTAINER(member) \
656 arrayParamOut(cp, #member, member)
657
658#define UNSERIALIZE_CONTAINER(member) \
659 arrayParamIn(cp, #member, member)
660
661#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event);
662
663#define UNSERIALIZE_EVENT(event) \
664 do { \
665 event.unserializeSection(cp, #event); \
666 eventQueue()->checkpointReschedule(&event); \
667 } while (0)
668
669#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj)
670#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj)
671
672#define SERIALIZE_OBJPTR(objptr) paramOut(cp, #objptr, (objptr)->name())
673
674#define UNSERIALIZE_OBJPTR(objptr) \
675 do { \
676 SimObject *sptr; \
677 objParamIn(cp, #objptr, sptr); \
678 objptr = dynamic_cast<decltype(objptr)>(sptr); \
679 } while (0)
680
681#endif // __SERIALIZE_HH__