serialize.cc (10907:94d5a1476c5b) serialize.cc (11072:6a447a3138ef)
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 *
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
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/framebuffer.hh"
59#include "base/inifile.hh"
60#include "base/misc.hh"
61#include "base/output.hh"
62#include "base/str.hh"
63#include "base/trace.hh"
64#include "debug/Checkpoint.hh"
65#include "sim/eventq.hh"
66#include "sim/serialize.hh"
67#include "sim/sim_events.hh"
68#include "sim/sim_exit.hh"
69#include "sim/sim_object.hh"
70
71// For stat reset hack
72#include "sim/stat_control.hh"
73
74using namespace std;
75
76//
77// The base implementations use to_number for parsing and '<<' for
78// displaying, suitable for integer types.
79//
80template <class T>
81bool
82parseParam(const string &s, T &value)
83{
84 return to_number(s, value);
85}
86
87template <class T>
88void
89showParam(CheckpointOut &os, const T &value)
90{
91 os << value;
92}
93
94//
95// Template specializations:
96// - char (8-bit integer)
97// - floating-point types
98// - bool
99// - string
100//
101
102// Treat 8-bit ints (chars) as ints on output, not as chars
103template <>
104void
105showParam(CheckpointOut &os, const char &value)
106{
107 os << (int)value;
108}
109
110
111template <>
112void
113showParam(CheckpointOut &os, const signed char &value)
114{
115 os << (int)value;
116}
117
118
119template <>
120void
121showParam(CheckpointOut &os, const unsigned char &value)
122{
123 os << (unsigned int)value;
124}
125
126
127template <>
128bool
129parseParam(const string &s, float &value)
130{
131 return to_number(s, value);
132}
133
134template <>
135bool
136parseParam(const string &s, double &value)
137{
138 return to_number(s, value);
139}
140
141template <>
142bool
143parseParam(const string &s, bool &value)
144{
145 return to_bool(s, value);
146}
147
148// Display bools as strings
149template <>
150void
151showParam(CheckpointOut &os, const bool &value)
152{
153 os << (value ? "true" : "false");
154}
155
156
157// String requires no processing to speak of
158template <>
159bool
160parseParam(const string &s, string &value)
161{
162 value = s;
163 return true;
164}
165
166int Serializable::ckptMaxCount = 0;
167int Serializable::ckptCount = 0;
168int Serializable::ckptPrevCount = -1;
169std::stack<std::string> Serializable::path;
170
171template <class T>
172void
173paramOut(CheckpointOut &os, const string &name, const T &param)
174{
175 os << name << "=";
176 showParam(os, param);
177 os << "\n";
178}
179
180template <class T>
181void
182arrayParamOut(CheckpointOut &os, const string &name, const vector<T> &param)
183{
184 typename vector<T>::size_type size = param.size();
185 os << name << "=";
186 if (size > 0)
187 showParam(os, param[0]);
188 for (typename vector<T>::size_type i = 1; i < size; ++i) {
189 os << " ";
190 showParam(os, param[i]);
191 }
192 os << "\n";
193}
194
195template <class T>
196void
197arrayParamOut(CheckpointOut &os, const string &name, const list<T> &param)
198{
199 typename list<T>::const_iterator it = param.begin();
200
201 os << name << "=";
202 if (param.size() > 0)
203 showParam(os, *it);
204 it++;
205 while (it != param.end()) {
206 os << " ";
207 showParam(os, *it);
208 it++;
209 }
210 os << "\n";
211}
212
213template <class T>
214void
215paramIn(CheckpointIn &cp, const string &name, T &param)
216{
217 const string &section(Serializable::currentSection());
218 string str;
219 if (!cp.find(section, name, str) || !parseParam(str, param)) {
220 fatal("Can't unserialize '%s:%s'\n", section, name);
221 }
222}
223
224template <class T>
225bool
226optParamIn(CheckpointIn &cp, const string &name, T &param)
227{
228 const string &section(Serializable::currentSection());
229 string str;
230 if (!cp.find(section, name, str) || !parseParam(str, param)) {
231 warn("optional parameter %s:%s not present\n", section, name);
232 return false;
233 } else {
234 return true;
235 }
236}
237
238template <class T>
239void
240arrayParamOut(CheckpointOut &os, const string &name,
241 const T *param, unsigned size)
242{
243 os << name << "=";
244 if (size > 0)
245 showParam(os, param[0]);
246 for (unsigned i = 1; i < size; ++i) {
247 os << " ";
248 showParam(os, param[i]);
249 }
250 os << "\n";
251}
252
253
254template <class T>
255void
256arrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
257{
258 const string &section(Serializable::currentSection());
259 string str;
260 if (!cp.find(section, name, str)) {
261 fatal("Can't unserialize '%s:%s'\n", section, name);
262 }
263
264 // code below stolen from VectorParam<T>::parse().
265 // it would be nice to unify these somehow...
266
267 vector<string> tokens;
268
269 tokenize(tokens, str, ' ');
270
271 // Need this if we were doing a vector
272 // value.resize(tokens.size());
273
274 if (tokens.size() != size) {
275 fatal("Array size mismatch on %s:%s'\n", section, name);
276 }
277
278 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
279 // need to parse into local variable to handle vector<bool>,
280 // for which operator[] returns a special reference class
281 // that's not the same as 'bool&', (since it's a packed
282 // vector)
283 T scalar_value;
284 if (!parseParam(tokens[i], scalar_value)) {
285 string err("could not parse \"");
286
287 err += str;
288 err += "\"";
289
290 fatal(err);
291 }
292
293 // assign parsed value to vector
294 param[i] = scalar_value;
295 }
296}
297
298template <class T>
299void
300arrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
301{
302 const string &section(Serializable::currentSection());
303 string str;
304 if (!cp.find(section, name, str)) {
305 fatal("Can't unserialize '%s:%s'\n", section, name);
306 }
307
308 // code below stolen from VectorParam<T>::parse().
309 // it would be nice to unify these somehow...
310
311 vector<string> tokens;
312
313 tokenize(tokens, str, ' ');
314
315 // Need this if we were doing a vector
316 // value.resize(tokens.size());
317
318 param.resize(tokens.size());
319
320 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
321 // need to parse into local variable to handle vector<bool>,
322 // for which operator[] returns a special reference class
323 // that's not the same as 'bool&', (since it's a packed
324 // vector)
325 T scalar_value;
326 if (!parseParam(tokens[i], scalar_value)) {
327 string err("could not parse \"");
328
329 err += str;
330 err += "\"";
331
332 fatal(err);
333 }
334
335 // assign parsed value to vector
336 param[i] = scalar_value;
337 }
338}
339
340template <class T>
341void
342arrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
343{
344 const string &section(Serializable::currentSection());
345 string str;
346 if (!cp.find(section, name, str)) {
347 fatal("Can't unserialize '%s:%s'\n", section, name);
348 }
349 param.clear();
350
351 vector<string> tokens;
352 tokenize(tokens, str, ' ');
353
354 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
355 T scalar_value;
356 if (!parseParam(tokens[i], scalar_value)) {
357 string err("could not parse \"");
358
359 err += str;
360 err += "\"";
361
362 fatal(err);
363 }
364
365 // assign parsed value to vector
366 param.push_back(scalar_value);
367 }
368}
369
370
371void
372objParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
373{
374 const string &section(Serializable::currentSection());
375 if (!cp.findObj(section, name, param)) {
376 fatal("Can't unserialize '%s:%s'\n", section, name);
377 }
378}
379
380
381#define INSTANTIATE_PARAM_TEMPLATES(type) \
382 template void \
383 paramOut(CheckpointOut &os, const string &name, type const &param); \
384 template void \
385 paramIn(CheckpointIn &cp, const string &name, type & param); \
386 template bool \
387 optParamIn(CheckpointIn &cp, const string &name, type & param); \
388 template void \
389 arrayParamOut(CheckpointOut &os, const string &name, \
390 type const *param, unsigned size); \
391 template void \
392 arrayParamIn(CheckpointIn &cp, const string &name, \
393 type *param, unsigned size); \
394 template void \
395 arrayParamOut(CheckpointOut &os, const string &name, \
396 const vector<type> &param); \
397 template void \
398 arrayParamIn(CheckpointIn &cp, const string &name, \
399 vector<type> &param); \
400 template void \
401 arrayParamOut(CheckpointOut &os, const string &name, \
402 const list<type> &param); \
403 template void \
404 arrayParamIn(CheckpointIn &cp, const string &name, \
405 list<type> &param);
406
407INSTANTIATE_PARAM_TEMPLATES(char)
408INSTANTIATE_PARAM_TEMPLATES(signed char)
409INSTANTIATE_PARAM_TEMPLATES(unsigned char)
410INSTANTIATE_PARAM_TEMPLATES(signed short)
411INSTANTIATE_PARAM_TEMPLATES(unsigned short)
412INSTANTIATE_PARAM_TEMPLATES(signed int)
413INSTANTIATE_PARAM_TEMPLATES(unsigned int)
414INSTANTIATE_PARAM_TEMPLATES(signed long)
415INSTANTIATE_PARAM_TEMPLATES(unsigned long)
416INSTANTIATE_PARAM_TEMPLATES(signed long long)
417INSTANTIATE_PARAM_TEMPLATES(unsigned long long)
418INSTANTIATE_PARAM_TEMPLATES(bool)
419INSTANTIATE_PARAM_TEMPLATES(float)
420INSTANTIATE_PARAM_TEMPLATES(double)
421INSTANTIATE_PARAM_TEMPLATES(string)
422INSTANTIATE_PARAM_TEMPLATES(Pixel)
423
424
425/////////////////////////////
426
427/// Container for serializing global variables (not associated with
428/// any serialized object).
429class Globals : public Serializable
430{
431 public:
432 Globals()
433 : unserializedCurTick(0) {}
434
435 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
436 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
437
438 Tick unserializedCurTick;
439};
440
441/// The one and only instance of the Globals class.
442Globals globals;
443
444void
445Globals::serialize(CheckpointOut &cp) const
446{
447 paramOut(cp, "curTick", curTick());
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 *
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
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/framebuffer.hh"
59#include "base/inifile.hh"
60#include "base/misc.hh"
61#include "base/output.hh"
62#include "base/str.hh"
63#include "base/trace.hh"
64#include "debug/Checkpoint.hh"
65#include "sim/eventq.hh"
66#include "sim/serialize.hh"
67#include "sim/sim_events.hh"
68#include "sim/sim_exit.hh"
69#include "sim/sim_object.hh"
70
71// For stat reset hack
72#include "sim/stat_control.hh"
73
74using namespace std;
75
76//
77// The base implementations use to_number for parsing and '<<' for
78// displaying, suitable for integer types.
79//
80template <class T>
81bool
82parseParam(const string &s, T &value)
83{
84 return to_number(s, value);
85}
86
87template <class T>
88void
89showParam(CheckpointOut &os, const T &value)
90{
91 os << value;
92}
93
94//
95// Template specializations:
96// - char (8-bit integer)
97// - floating-point types
98// - bool
99// - string
100//
101
102// Treat 8-bit ints (chars) as ints on output, not as chars
103template <>
104void
105showParam(CheckpointOut &os, const char &value)
106{
107 os << (int)value;
108}
109
110
111template <>
112void
113showParam(CheckpointOut &os, const signed char &value)
114{
115 os << (int)value;
116}
117
118
119template <>
120void
121showParam(CheckpointOut &os, const unsigned char &value)
122{
123 os << (unsigned int)value;
124}
125
126
127template <>
128bool
129parseParam(const string &s, float &value)
130{
131 return to_number(s, value);
132}
133
134template <>
135bool
136parseParam(const string &s, double &value)
137{
138 return to_number(s, value);
139}
140
141template <>
142bool
143parseParam(const string &s, bool &value)
144{
145 return to_bool(s, value);
146}
147
148// Display bools as strings
149template <>
150void
151showParam(CheckpointOut &os, const bool &value)
152{
153 os << (value ? "true" : "false");
154}
155
156
157// String requires no processing to speak of
158template <>
159bool
160parseParam(const string &s, string &value)
161{
162 value = s;
163 return true;
164}
165
166int Serializable::ckptMaxCount = 0;
167int Serializable::ckptCount = 0;
168int Serializable::ckptPrevCount = -1;
169std::stack<std::string> Serializable::path;
170
171template <class T>
172void
173paramOut(CheckpointOut &os, const string &name, const T &param)
174{
175 os << name << "=";
176 showParam(os, param);
177 os << "\n";
178}
179
180template <class T>
181void
182arrayParamOut(CheckpointOut &os, const string &name, const vector<T> &param)
183{
184 typename vector<T>::size_type size = param.size();
185 os << name << "=";
186 if (size > 0)
187 showParam(os, param[0]);
188 for (typename vector<T>::size_type i = 1; i < size; ++i) {
189 os << " ";
190 showParam(os, param[i]);
191 }
192 os << "\n";
193}
194
195template <class T>
196void
197arrayParamOut(CheckpointOut &os, const string &name, const list<T> &param)
198{
199 typename list<T>::const_iterator it = param.begin();
200
201 os << name << "=";
202 if (param.size() > 0)
203 showParam(os, *it);
204 it++;
205 while (it != param.end()) {
206 os << " ";
207 showParam(os, *it);
208 it++;
209 }
210 os << "\n";
211}
212
213template <class T>
214void
215paramIn(CheckpointIn &cp, const string &name, T &param)
216{
217 const string &section(Serializable::currentSection());
218 string str;
219 if (!cp.find(section, name, str) || !parseParam(str, param)) {
220 fatal("Can't unserialize '%s:%s'\n", section, name);
221 }
222}
223
224template <class T>
225bool
226optParamIn(CheckpointIn &cp, const string &name, T &param)
227{
228 const string &section(Serializable::currentSection());
229 string str;
230 if (!cp.find(section, name, str) || !parseParam(str, param)) {
231 warn("optional parameter %s:%s not present\n", section, name);
232 return false;
233 } else {
234 return true;
235 }
236}
237
238template <class T>
239void
240arrayParamOut(CheckpointOut &os, const string &name,
241 const T *param, unsigned size)
242{
243 os << name << "=";
244 if (size > 0)
245 showParam(os, param[0]);
246 for (unsigned i = 1; i < size; ++i) {
247 os << " ";
248 showParam(os, param[i]);
249 }
250 os << "\n";
251}
252
253
254template <class T>
255void
256arrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
257{
258 const string &section(Serializable::currentSection());
259 string str;
260 if (!cp.find(section, name, str)) {
261 fatal("Can't unserialize '%s:%s'\n", section, name);
262 }
263
264 // code below stolen from VectorParam<T>::parse().
265 // it would be nice to unify these somehow...
266
267 vector<string> tokens;
268
269 tokenize(tokens, str, ' ');
270
271 // Need this if we were doing a vector
272 // value.resize(tokens.size());
273
274 if (tokens.size() != size) {
275 fatal("Array size mismatch on %s:%s'\n", section, name);
276 }
277
278 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
279 // need to parse into local variable to handle vector<bool>,
280 // for which operator[] returns a special reference class
281 // that's not the same as 'bool&', (since it's a packed
282 // vector)
283 T scalar_value;
284 if (!parseParam(tokens[i], scalar_value)) {
285 string err("could not parse \"");
286
287 err += str;
288 err += "\"";
289
290 fatal(err);
291 }
292
293 // assign parsed value to vector
294 param[i] = scalar_value;
295 }
296}
297
298template <class T>
299void
300arrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
301{
302 const string &section(Serializable::currentSection());
303 string str;
304 if (!cp.find(section, name, str)) {
305 fatal("Can't unserialize '%s:%s'\n", section, name);
306 }
307
308 // code below stolen from VectorParam<T>::parse().
309 // it would be nice to unify these somehow...
310
311 vector<string> tokens;
312
313 tokenize(tokens, str, ' ');
314
315 // Need this if we were doing a vector
316 // value.resize(tokens.size());
317
318 param.resize(tokens.size());
319
320 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
321 // need to parse into local variable to handle vector<bool>,
322 // for which operator[] returns a special reference class
323 // that's not the same as 'bool&', (since it's a packed
324 // vector)
325 T scalar_value;
326 if (!parseParam(tokens[i], scalar_value)) {
327 string err("could not parse \"");
328
329 err += str;
330 err += "\"";
331
332 fatal(err);
333 }
334
335 // assign parsed value to vector
336 param[i] = scalar_value;
337 }
338}
339
340template <class T>
341void
342arrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
343{
344 const string &section(Serializable::currentSection());
345 string str;
346 if (!cp.find(section, name, str)) {
347 fatal("Can't unserialize '%s:%s'\n", section, name);
348 }
349 param.clear();
350
351 vector<string> tokens;
352 tokenize(tokens, str, ' ');
353
354 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
355 T scalar_value;
356 if (!parseParam(tokens[i], scalar_value)) {
357 string err("could not parse \"");
358
359 err += str;
360 err += "\"";
361
362 fatal(err);
363 }
364
365 // assign parsed value to vector
366 param.push_back(scalar_value);
367 }
368}
369
370
371void
372objParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
373{
374 const string &section(Serializable::currentSection());
375 if (!cp.findObj(section, name, param)) {
376 fatal("Can't unserialize '%s:%s'\n", section, name);
377 }
378}
379
380
381#define INSTANTIATE_PARAM_TEMPLATES(type) \
382 template void \
383 paramOut(CheckpointOut &os, const string &name, type const &param); \
384 template void \
385 paramIn(CheckpointIn &cp, const string &name, type & param); \
386 template bool \
387 optParamIn(CheckpointIn &cp, const string &name, type & param); \
388 template void \
389 arrayParamOut(CheckpointOut &os, const string &name, \
390 type const *param, unsigned size); \
391 template void \
392 arrayParamIn(CheckpointIn &cp, const string &name, \
393 type *param, unsigned size); \
394 template void \
395 arrayParamOut(CheckpointOut &os, const string &name, \
396 const vector<type> &param); \
397 template void \
398 arrayParamIn(CheckpointIn &cp, const string &name, \
399 vector<type> &param); \
400 template void \
401 arrayParamOut(CheckpointOut &os, const string &name, \
402 const list<type> &param); \
403 template void \
404 arrayParamIn(CheckpointIn &cp, const string &name, \
405 list<type> &param);
406
407INSTANTIATE_PARAM_TEMPLATES(char)
408INSTANTIATE_PARAM_TEMPLATES(signed char)
409INSTANTIATE_PARAM_TEMPLATES(unsigned char)
410INSTANTIATE_PARAM_TEMPLATES(signed short)
411INSTANTIATE_PARAM_TEMPLATES(unsigned short)
412INSTANTIATE_PARAM_TEMPLATES(signed int)
413INSTANTIATE_PARAM_TEMPLATES(unsigned int)
414INSTANTIATE_PARAM_TEMPLATES(signed long)
415INSTANTIATE_PARAM_TEMPLATES(unsigned long)
416INSTANTIATE_PARAM_TEMPLATES(signed long long)
417INSTANTIATE_PARAM_TEMPLATES(unsigned long long)
418INSTANTIATE_PARAM_TEMPLATES(bool)
419INSTANTIATE_PARAM_TEMPLATES(float)
420INSTANTIATE_PARAM_TEMPLATES(double)
421INSTANTIATE_PARAM_TEMPLATES(string)
422INSTANTIATE_PARAM_TEMPLATES(Pixel)
423
424
425/////////////////////////////
426
427/// Container for serializing global variables (not associated with
428/// any serialized object).
429class Globals : public Serializable
430{
431 public:
432 Globals()
433 : unserializedCurTick(0) {}
434
435 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
436 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
437
438 Tick unserializedCurTick;
439};
440
441/// The one and only instance of the Globals class.
442Globals globals;
443
444void
445Globals::serialize(CheckpointOut &cp) const
446{
447 paramOut(cp, "curTick", curTick());
448 paramOut(cp, "numMainEventQueues", numMainEventQueues);
449
450}
451
452void
453Globals::unserialize(CheckpointIn &cp)
454{
455 paramIn(cp, "curTick", unserializedCurTick);
448}
449
450void
451Globals::unserialize(CheckpointIn &cp)
452{
453 paramIn(cp, "curTick", unserializedCurTick);
456 paramIn(cp, "numMainEventQueues", numMainEventQueues);
457}
458
459Serializable::Serializable()
460{
461}
462
463Serializable::~Serializable()
464{
465}
466
467void
468Serializable::serializeSection(CheckpointOut &cp, const char *name) const
469{
470 Serializable::ScopedCheckpointSection sec(cp, name);
471 serialize(cp);
472}
473
474void
475Serializable::serializeSectionOld(CheckpointOut &cp, const char *name)
476{
477 Serializable::ScopedCheckpointSection sec(cp, name);
478 serializeOld(cp);
479}
480
481void
482Serializable::unserializeSection(CheckpointIn &cp, const char *name)
483{
484 Serializable::ScopedCheckpointSection sec(cp, name);
485 unserialize(cp);
486}
487
488void
489Serializable::serializeAll(const string &cpt_dir)
490{
491 string dir = CheckpointIn::setDir(cpt_dir);
492 if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
493 fatal("couldn't mkdir %s\n", dir);
494
495 string cpt_file = dir + CheckpointIn::baseFilename;
496 ofstream outstream(cpt_file.c_str());
497 time_t t = time(NULL);
498 if (!outstream.is_open())
499 fatal("Unable to open file %s for writing\n", cpt_file.c_str());
500 outstream << "## checkpoint generated: " << ctime(&t);
501
502 globals.serializeSection(outstream, "Globals");
454}
455
456Serializable::Serializable()
457{
458}
459
460Serializable::~Serializable()
461{
462}
463
464void
465Serializable::serializeSection(CheckpointOut &cp, const char *name) const
466{
467 Serializable::ScopedCheckpointSection sec(cp, name);
468 serialize(cp);
469}
470
471void
472Serializable::serializeSectionOld(CheckpointOut &cp, const char *name)
473{
474 Serializable::ScopedCheckpointSection sec(cp, name);
475 serializeOld(cp);
476}
477
478void
479Serializable::unserializeSection(CheckpointIn &cp, const char *name)
480{
481 Serializable::ScopedCheckpointSection sec(cp, name);
482 unserialize(cp);
483}
484
485void
486Serializable::serializeAll(const string &cpt_dir)
487{
488 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
492 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
499 globals.serializeSection(outstream, "Globals");
503 for (uint32_t i = 0; i < numMainEventQueues; ++i)
504 mainEventQueue[i]->serializeSection(outstream, "MainEventQueue");
505
506 SimObject::serializeAll(outstream);
507}
508
509void
510Serializable::unserializeGlobals(CheckpointIn &cp)
511{
512 globals.unserializeSection(cp, "Globals");
513
500
501 SimObject::serializeAll(outstream);
502}
503
504void
505Serializable::unserializeGlobals(CheckpointIn &cp)
506{
507 globals.unserializeSection(cp, "Globals");
508
514 for (uint32_t i = 0; i < numMainEventQueues; ++i) {
509 for (uint32_t i = 0; i < numMainEventQueues; ++i)
515 mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
510 mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
516 mainEventQueue[i]->unserializeSection(cp, "MainEventQueue");
517 }
518}
519
520Serializable::ScopedCheckpointSection::~ScopedCheckpointSection()
521{
522 assert(!path.empty());
523 DPRINTF(Checkpoint, "Popping: %s\n", path.top());
524 path.pop();
525}
526
527void
528Serializable::ScopedCheckpointSection::pushName(const char *obj_name)
529{
530 if (path.empty()) {
531 path.push(obj_name);
532 } else {
533 path.push(csprintf("%s.%s", path.top(), obj_name));
534 }
535 DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
536}
537
538void
539Serializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
540{
541 DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
542 Serializable::currentSection());
543 cp << "\n[" << Serializable::currentSection() << "]\n";
544}
545
546void
547debug_serialize(const string &cpt_dir)
548{
549 Serializable::serializeAll(cpt_dir);
550}
551
511}
512
513Serializable::ScopedCheckpointSection::~ScopedCheckpointSection()
514{
515 assert(!path.empty());
516 DPRINTF(Checkpoint, "Popping: %s\n", path.top());
517 path.pop();
518}
519
520void
521Serializable::ScopedCheckpointSection::pushName(const char *obj_name)
522{
523 if (path.empty()) {
524 path.push(obj_name);
525 } else {
526 path.push(csprintf("%s.%s", path.top(), obj_name));
527 }
528 DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
529}
530
531void
532Serializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
533{
534 DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
535 Serializable::currentSection());
536 cp << "\n[" << Serializable::currentSection() << "]\n";
537}
538
539void
540debug_serialize(const string &cpt_dir)
541{
542 Serializable::serializeAll(cpt_dir);
543}
544
552
553////////////////////////////////////////////////////////////////////////
554//
555// SerializableClass member definitions
556//
557////////////////////////////////////////////////////////////////////////
558
559// Map of class names to SerializableBuilder creation functions.
560// Need to make this a pointer so we can force initialization on the
561// first reference; otherwise, some SerializableClass constructors
562// may be invoked before the classMap constructor.
563map<string, SerializableClass::CreateFunc> *SerializableClass::classMap = 0;
564
565// SerializableClass constructor: add mapping to classMap
566SerializableClass::SerializableClass(const string &className,
567 CreateFunc createFunc)
568{
569 if (classMap == NULL)
570 classMap = new map<string, SerializableClass::CreateFunc>();
571
572 if ((*classMap)[className])
573 fatal("Error: simulation object class %s redefined\n", className);
574
575 // add className --> createFunc to class map
576 (*classMap)[className] = createFunc;
577}
578
579//
580//
581Serializable *
582SerializableClass::createObject(CheckpointIn &cp, const string &section)
583{
584 string className;
585
586 if (!cp.find(section, "type", className)) {
587 fatal("Serializable::create: no 'type' entry in section '%s'.\n",
588 section);
589 }
590
591 CreateFunc createFunc = (*classMap)[className];
592
593 if (createFunc == NULL) {
594 fatal("Serializable::create: no create function for class '%s'.\n",
595 className);
596 }
597
598 Serializable *object = createFunc(cp, section);
599
600 assert(object != NULL);
601
602 return object;
603}
604
605const std::string &
606Serializable::currentSection()
607{
608 assert(!path.empty());
609
610 return path.top();
611}
612
545const std::string &
546Serializable::currentSection()
547{
548 assert(!path.empty());
549
550 return path.top();
551}
552
613Serializable *
614Serializable::create(CheckpointIn &cp, const string &section)
615{
616 Serializable *object = SerializableClass::createObject(cp, section);
617 object->unserializeSection(cp, section);
618 return object;
619}
620
621
622const char *CheckpointIn::baseFilename = "m5.cpt";
623
624string CheckpointIn::currentDirectory;
625
626string
627CheckpointIn::setDir(const string &name)
628{
629 // use csprintf to insert curTick() into directory name if it
630 // appears to have a format placeholder in it.
631 currentDirectory = (name.find("%") != string::npos) ?
632 csprintf(name, curTick()) : name;
633 if (currentDirectory[currentDirectory.size() - 1] != '/')
634 currentDirectory += "/";
635 return currentDirectory;
636}
637
638string
639CheckpointIn::dir()
640{
641 return currentDirectory;
642}
643
644
645CheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
646 : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
647{
648 string filename = cptDir + "/" + CheckpointIn::baseFilename;
649 if (!db->load(filename)) {
650 fatal("Can't load checkpoint file '%s'\n", filename);
651 }
652}
653
654CheckpointIn::~CheckpointIn()
655{
656 delete db;
657}
658
659bool
660CheckpointIn::find(const string &section, const string &entry, string &value)
661{
662 return db->find(section, entry, value);
663}
664
665
666bool
667CheckpointIn::findObj(const string &section, const string &entry,
668 SimObject *&value)
669{
670 string path;
671
672 if (!db->find(section, entry, path))
673 return false;
674
675 value = objNameResolver.resolveSimObject(path);
676 return true;
677}
678
679
680bool
681CheckpointIn::sectionExists(const string &section)
682{
683 return db->sectionExists(section);
684}
553const char *CheckpointIn::baseFilename = "m5.cpt";
554
555string CheckpointIn::currentDirectory;
556
557string
558CheckpointIn::setDir(const string &name)
559{
560 // use csprintf to insert curTick() into directory name if it
561 // appears to have a format placeholder in it.
562 currentDirectory = (name.find("%") != string::npos) ?
563 csprintf(name, curTick()) : name;
564 if (currentDirectory[currentDirectory.size() - 1] != '/')
565 currentDirectory += "/";
566 return currentDirectory;
567}
568
569string
570CheckpointIn::dir()
571{
572 return currentDirectory;
573}
574
575
576CheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
577 : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
578{
579 string filename = cptDir + "/" + CheckpointIn::baseFilename;
580 if (!db->load(filename)) {
581 fatal("Can't load checkpoint file '%s'\n", filename);
582 }
583}
584
585CheckpointIn::~CheckpointIn()
586{
587 delete db;
588}
589
590bool
591CheckpointIn::find(const string &section, const string &entry, string &value)
592{
593 return db->find(section, entry, value);
594}
595
596
597bool
598CheckpointIn::findObj(const string &section, const string &entry,
599 SimObject *&value)
600{
601 string path;
602
603 if (!db->find(section, entry, path))
604 return false;
605
606 value = objNameResolver.resolveSimObject(path);
607 return true;
608}
609
610
611bool
612CheckpointIn::sectionExists(const string &section)
613{
614 return db->sectionExists(section);
615}