serialize.cc (11075:f959b7f89d4d) serialize.cc (11076:463a4b0f0dda)
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
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
215arrayParamOut(CheckpointOut &os, const string &name, const set<T> &param)
216{
217 typename set<T>::const_iterator it = param.begin();
218
219 os << name << "=";
220 if (param.size() > 0)
221 showParam(os, *it);
222 it++;
223 while (it != param.end()) {
224 os << " ";
225 showParam(os, *it);
226 it++;
227 }
228 os << "\n";
229}
230
231template <class T>
232void
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, bool warn)
227{
228 const string &section(Serializable::currentSection());
229 string str;
230 if (!cp.find(section, name, str) || !parseParam(str, param)) {
231 if (warn)
232 warn("optional parameter %s:%s not present\n", section, name);
233 return false;
234 } else {
235 return true;
236 }
237}
238
239template <class T>
240void
241arrayParamOut(CheckpointOut &os, const string &name,
242 const T *param, unsigned size)
243{
244 os << name << "=";
245 if (size > 0)
246 showParam(os, param[0]);
247 for (unsigned i = 1; i < size; ++i) {
248 os << " ";
249 showParam(os, param[i]);
250 }
251 os << "\n";
252}
253
254
255template <class T>
256void
257arrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
258{
259 const string &section(Serializable::currentSection());
260 string str;
261 if (!cp.find(section, name, str)) {
262 fatal("Can't unserialize '%s:%s'\n", section, name);
263 }
264
265 // code below stolen from VectorParam<T>::parse().
266 // it would be nice to unify these somehow...
267
268 vector<string> tokens;
269
270 tokenize(tokens, str, ' ');
271
272 // Need this if we were doing a vector
273 // value.resize(tokens.size());
274
275 if (tokens.size() != size) {
276 fatal("Array size mismatch on %s:%s'\n", section, name);
277 }
278
279 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
280 // need to parse into local variable to handle vector<bool>,
281 // for which operator[] returns a special reference class
282 // that's not the same as 'bool&', (since it's a packed
283 // vector)
284 T scalar_value;
285 if (!parseParam(tokens[i], scalar_value)) {
286 string err("could not parse \"");
287
288 err += str;
289 err += "\"";
290
291 fatal(err);
292 }
293
294 // assign parsed value to vector
295 param[i] = scalar_value;
296 }
297}
298
299template <class T>
300void
301arrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
302{
303 const string &section(Serializable::currentSection());
304 string str;
305 if (!cp.find(section, name, str)) {
306 fatal("Can't unserialize '%s:%s'\n", section, name);
307 }
308
309 // code below stolen from VectorParam<T>::parse().
310 // it would be nice to unify these somehow...
311
312 vector<string> tokens;
313
314 tokenize(tokens, str, ' ');
315
316 // Need this if we were doing a vector
317 // value.resize(tokens.size());
318
319 param.resize(tokens.size());
320
321 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
322 // need to parse into local variable to handle vector<bool>,
323 // for which operator[] returns a special reference class
324 // that's not the same as 'bool&', (since it's a packed
325 // vector)
326 T scalar_value;
327 if (!parseParam(tokens[i], scalar_value)) {
328 string err("could not parse \"");
329
330 err += str;
331 err += "\"";
332
333 fatal(err);
334 }
335
336 // assign parsed value to vector
337 param[i] = scalar_value;
338 }
339}
340
341template <class T>
342void
343arrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
344{
345 const string &section(Serializable::currentSection());
346 string str;
347 if (!cp.find(section, name, str)) {
348 fatal("Can't unserialize '%s:%s'\n", section, name);
349 }
350 param.clear();
351
352 vector<string> tokens;
353 tokenize(tokens, str, ' ');
354
355 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
356 T scalar_value;
357 if (!parseParam(tokens[i], scalar_value)) {
358 string err("could not parse \"");
359
360 err += str;
361 err += "\"";
362
363 fatal(err);
364 }
365
366 // assign parsed value to vector
367 param.push_back(scalar_value);
368 }
369}
370
233paramIn(CheckpointIn &cp, const string &name, T &param)
234{
235 const string &section(Serializable::currentSection());
236 string str;
237 if (!cp.find(section, name, str) || !parseParam(str, param)) {
238 fatal("Can't unserialize '%s:%s'\n", section, name);
239 }
240}
241
242template <class T>
243bool
244optParamIn(CheckpointIn &cp, const string &name, T &param, bool warn)
245{
246 const string &section(Serializable::currentSection());
247 string str;
248 if (!cp.find(section, name, str) || !parseParam(str, param)) {
249 if (warn)
250 warn("optional parameter %s:%s not present\n", section, name);
251 return false;
252 } else {
253 return true;
254 }
255}
256
257template <class T>
258void
259arrayParamOut(CheckpointOut &os, const string &name,
260 const T *param, unsigned size)
261{
262 os << name << "=";
263 if (size > 0)
264 showParam(os, param[0]);
265 for (unsigned i = 1; i < size; ++i) {
266 os << " ";
267 showParam(os, param[i]);
268 }
269 os << "\n";
270}
271
272
273template <class T>
274void
275arrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
276{
277 const string &section(Serializable::currentSection());
278 string str;
279 if (!cp.find(section, name, str)) {
280 fatal("Can't unserialize '%s:%s'\n", section, name);
281 }
282
283 // code below stolen from VectorParam<T>::parse().
284 // it would be nice to unify these somehow...
285
286 vector<string> tokens;
287
288 tokenize(tokens, str, ' ');
289
290 // Need this if we were doing a vector
291 // value.resize(tokens.size());
292
293 if (tokens.size() != size) {
294 fatal("Array size mismatch on %s:%s'\n", section, name);
295 }
296
297 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
298 // need to parse into local variable to handle vector<bool>,
299 // for which operator[] returns a special reference class
300 // that's not the same as 'bool&', (since it's a packed
301 // vector)
302 T scalar_value;
303 if (!parseParam(tokens[i], scalar_value)) {
304 string err("could not parse \"");
305
306 err += str;
307 err += "\"";
308
309 fatal(err);
310 }
311
312 // assign parsed value to vector
313 param[i] = scalar_value;
314 }
315}
316
317template <class T>
318void
319arrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
320{
321 const string &section(Serializable::currentSection());
322 string str;
323 if (!cp.find(section, name, str)) {
324 fatal("Can't unserialize '%s:%s'\n", section, name);
325 }
326
327 // code below stolen from VectorParam<T>::parse().
328 // it would be nice to unify these somehow...
329
330 vector<string> tokens;
331
332 tokenize(tokens, str, ' ');
333
334 // Need this if we were doing a vector
335 // value.resize(tokens.size());
336
337 param.resize(tokens.size());
338
339 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
340 // need to parse into local variable to handle vector<bool>,
341 // for which operator[] returns a special reference class
342 // that's not the same as 'bool&', (since it's a packed
343 // vector)
344 T scalar_value;
345 if (!parseParam(tokens[i], scalar_value)) {
346 string err("could not parse \"");
347
348 err += str;
349 err += "\"";
350
351 fatal(err);
352 }
353
354 // assign parsed value to vector
355 param[i] = scalar_value;
356 }
357}
358
359template <class T>
360void
361arrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
362{
363 const string &section(Serializable::currentSection());
364 string str;
365 if (!cp.find(section, name, str)) {
366 fatal("Can't unserialize '%s:%s'\n", section, name);
367 }
368 param.clear();
369
370 vector<string> tokens;
371 tokenize(tokens, str, ' ');
372
373 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
374 T scalar_value;
375 if (!parseParam(tokens[i], scalar_value)) {
376 string err("could not parse \"");
377
378 err += str;
379 err += "\"";
380
381 fatal(err);
382 }
383
384 // assign parsed value to vector
385 param.push_back(scalar_value);
386 }
387}
388
389template <class T>
390void
391arrayParamIn(CheckpointIn &cp, const string &name, set<T> &param)
392{
393 const string &section(Serializable::currentSection());
394 string str;
395 if (!cp.find(section, name, str)) {
396 fatal("Can't unserialize '%s:%s'\n", section, name);
397 }
398 param.clear();
371
399
400 vector<string> tokens;
401 tokenize(tokens, str, ' ');
402
403 for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
404 T scalar_value;
405 if (!parseParam(tokens[i], scalar_value)) {
406 string err("could not parse \"");
407
408 err += str;
409 err += "\"";
410
411 fatal(err);
412 }
413
414 // assign parsed value to vector
415 param.insert(scalar_value);
416 }
417}
418
419
372void
373objParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
374{
375 const string &section(Serializable::currentSection());
376 if (!cp.findObj(section, name, param)) {
377 fatal("Can't unserialize '%s:%s'\n", section, name);
378 }
379}
380
381
382#define INSTANTIATE_PARAM_TEMPLATES(type) \
383 template void \
384 paramOut(CheckpointOut &os, const string &name, type const &param); \
385 template void \
386 paramIn(CheckpointIn &cp, const string &name, type & param); \
387 template bool \
388 optParamIn(CheckpointIn &cp, const string &name, type & param, \
389 bool warn); \
390 template void \
391 arrayParamOut(CheckpointOut &os, const string &name, \
392 type const *param, unsigned size); \
393 template void \
394 arrayParamIn(CheckpointIn &cp, const string &name, \
395 type *param, unsigned size); \
396 template void \
397 arrayParamOut(CheckpointOut &os, const string &name, \
398 const vector<type> &param); \
399 template void \
400 arrayParamIn(CheckpointIn &cp, const string &name, \
401 vector<type> &param); \
402 template void \
403 arrayParamOut(CheckpointOut &os, const string &name, \
404 const list<type> &param); \
405 template void \
406 arrayParamIn(CheckpointIn &cp, const string &name, \
407 list<type> &param);
408
409INSTANTIATE_PARAM_TEMPLATES(char)
410INSTANTIATE_PARAM_TEMPLATES(signed char)
411INSTANTIATE_PARAM_TEMPLATES(unsigned char)
412INSTANTIATE_PARAM_TEMPLATES(signed short)
413INSTANTIATE_PARAM_TEMPLATES(unsigned short)
414INSTANTIATE_PARAM_TEMPLATES(signed int)
415INSTANTIATE_PARAM_TEMPLATES(unsigned int)
416INSTANTIATE_PARAM_TEMPLATES(signed long)
417INSTANTIATE_PARAM_TEMPLATES(unsigned long)
418INSTANTIATE_PARAM_TEMPLATES(signed long long)
419INSTANTIATE_PARAM_TEMPLATES(unsigned long long)
420INSTANTIATE_PARAM_TEMPLATES(bool)
421INSTANTIATE_PARAM_TEMPLATES(float)
422INSTANTIATE_PARAM_TEMPLATES(double)
423INSTANTIATE_PARAM_TEMPLATES(string)
424INSTANTIATE_PARAM_TEMPLATES(Pixel)
425
420void
421objParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
422{
423 const string &section(Serializable::currentSection());
424 if (!cp.findObj(section, name, param)) {
425 fatal("Can't unserialize '%s:%s'\n", section, name);
426 }
427}
428
429
430#define INSTANTIATE_PARAM_TEMPLATES(type) \
431 template void \
432 paramOut(CheckpointOut &os, const string &name, type const &param); \
433 template void \
434 paramIn(CheckpointIn &cp, const string &name, type & param); \
435 template bool \
436 optParamIn(CheckpointIn &cp, const string &name, type & param, \
437 bool warn); \
438 template void \
439 arrayParamOut(CheckpointOut &os, const string &name, \
440 type const *param, unsigned size); \
441 template void \
442 arrayParamIn(CheckpointIn &cp, const string &name, \
443 type *param, unsigned size); \
444 template void \
445 arrayParamOut(CheckpointOut &os, const string &name, \
446 const vector<type> &param); \
447 template void \
448 arrayParamIn(CheckpointIn &cp, const string &name, \
449 vector<type> &param); \
450 template void \
451 arrayParamOut(CheckpointOut &os, const string &name, \
452 const list<type> &param); \
453 template void \
454 arrayParamIn(CheckpointIn &cp, const string &name, \
455 list<type> &param);
456
457INSTANTIATE_PARAM_TEMPLATES(char)
458INSTANTIATE_PARAM_TEMPLATES(signed char)
459INSTANTIATE_PARAM_TEMPLATES(unsigned char)
460INSTANTIATE_PARAM_TEMPLATES(signed short)
461INSTANTIATE_PARAM_TEMPLATES(unsigned short)
462INSTANTIATE_PARAM_TEMPLATES(signed int)
463INSTANTIATE_PARAM_TEMPLATES(unsigned int)
464INSTANTIATE_PARAM_TEMPLATES(signed long)
465INSTANTIATE_PARAM_TEMPLATES(unsigned long)
466INSTANTIATE_PARAM_TEMPLATES(signed long long)
467INSTANTIATE_PARAM_TEMPLATES(unsigned long long)
468INSTANTIATE_PARAM_TEMPLATES(bool)
469INSTANTIATE_PARAM_TEMPLATES(float)
470INSTANTIATE_PARAM_TEMPLATES(double)
471INSTANTIATE_PARAM_TEMPLATES(string)
472INSTANTIATE_PARAM_TEMPLATES(Pixel)
473
474// set is only used with strings and furthermore doesn't agree with Pixel
475template void
476arrayParamOut(CheckpointOut &, const string &, const set<string> &);
477template void
478arrayParamIn(CheckpointIn &, const string &, set<string> &);
426
427/////////////////////////////
428
429/// Container for serializing global variables (not associated with
430/// any serialized object).
431class Globals : public Serializable
432{
433 public:
434 Globals()
435 : unserializedCurTick(0) {}
436
437 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
438 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
439
440 Tick unserializedCurTick;
441};
442
443/// The one and only instance of the Globals class.
444Globals globals;
445
446void
447Globals::serialize(CheckpointOut &cp) const
448{
449 paramOut(cp, "curTick", curTick());
450}
451
452void
453Globals::unserialize(CheckpointIn &cp)
454{
455 paramIn(cp, "curTick", unserializedCurTick);
456}
457
458Serializable::Serializable()
459{
460}
461
462Serializable::~Serializable()
463{
464}
465
466void
467Serializable::serializeSection(CheckpointOut &cp, const char *name) const
468{
469 Serializable::ScopedCheckpointSection sec(cp, name);
470 serialize(cp);
471}
472
473void
474Serializable::serializeSectionOld(CheckpointOut &cp, const char *name)
475{
476 Serializable::ScopedCheckpointSection sec(cp, name);
477 serializeOld(cp);
478}
479
480void
481Serializable::unserializeSection(CheckpointIn &cp, const char *name)
482{
483 Serializable::ScopedCheckpointSection sec(cp, name);
484 unserialize(cp);
485}
486
487void
488Serializable::serializeAll(const string &cpt_dir)
489{
490 string dir = CheckpointIn::setDir(cpt_dir);
491 if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
492 fatal("couldn't mkdir %s\n", dir);
493
494 string cpt_file = dir + CheckpointIn::baseFilename;
495 ofstream outstream(cpt_file.c_str());
496 time_t t = time(NULL);
497 if (!outstream.is_open())
498 fatal("Unable to open file %s for writing\n", cpt_file.c_str());
499 outstream << "## checkpoint generated: " << ctime(&t);
500
501 globals.serializeSection(outstream, "Globals");
502
503 SimObject::serializeAll(outstream);
504}
505
506void
507Serializable::unserializeGlobals(CheckpointIn &cp)
508{
509 globals.unserializeSection(cp, "Globals");
510
511 for (uint32_t i = 0; i < numMainEventQueues; ++i)
512 mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
513}
514
515Serializable::ScopedCheckpointSection::~ScopedCheckpointSection()
516{
517 assert(!path.empty());
518 DPRINTF(Checkpoint, "Popping: %s\n", path.top());
519 path.pop();
520}
521
522void
523Serializable::ScopedCheckpointSection::pushName(const char *obj_name)
524{
525 if (path.empty()) {
526 path.push(obj_name);
527 } else {
528 path.push(csprintf("%s.%s", path.top(), obj_name));
529 }
530 DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
531}
532
533void
534Serializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
535{
536 DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
537 Serializable::currentSection());
538 cp << "\n[" << Serializable::currentSection() << "]\n";
539}
540
541void
542debug_serialize(const string &cpt_dir)
543{
544 Serializable::serializeAll(cpt_dir);
545}
546
547const std::string &
548Serializable::currentSection()
549{
550 assert(!path.empty());
551
552 return path.top();
553}
554
555const char *CheckpointIn::baseFilename = "m5.cpt";
556
557string CheckpointIn::currentDirectory;
558
559string
560CheckpointIn::setDir(const string &name)
561{
562 // use csprintf to insert curTick() into directory name if it
563 // appears to have a format placeholder in it.
564 currentDirectory = (name.find("%") != string::npos) ?
565 csprintf(name, curTick()) : name;
566 if (currentDirectory[currentDirectory.size() - 1] != '/')
567 currentDirectory += "/";
568 return currentDirectory;
569}
570
571string
572CheckpointIn::dir()
573{
574 return currentDirectory;
575}
576
577
578CheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
579 : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
580{
581 string filename = cptDir + "/" + CheckpointIn::baseFilename;
582 if (!db->load(filename)) {
583 fatal("Can't load checkpoint file '%s'\n", filename);
584 }
585}
586
587CheckpointIn::~CheckpointIn()
588{
589 delete db;
590}
591
592bool
593CheckpointIn::find(const string &section, const string &entry, string &value)
594{
595 return db->find(section, entry, value);
596}
597
598
599bool
600CheckpointIn::findObj(const string &section, const string &entry,
601 SimObject *&value)
602{
603 string path;
604
605 if (!db->find(section, entry, path))
606 return false;
607
608 value = objNameResolver.resolveSimObject(path);
609 return true;
610}
611
612
613bool
614CheckpointIn::sectionExists(const string &section)
615{
616 return db->sectionExists(section);
617}
479
480/////////////////////////////
481
482/// Container for serializing global variables (not associated with
483/// any serialized object).
484class Globals : public Serializable
485{
486 public:
487 Globals()
488 : unserializedCurTick(0) {}
489
490 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
491 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
492
493 Tick unserializedCurTick;
494};
495
496/// The one and only instance of the Globals class.
497Globals globals;
498
499void
500Globals::serialize(CheckpointOut &cp) const
501{
502 paramOut(cp, "curTick", curTick());
503}
504
505void
506Globals::unserialize(CheckpointIn &cp)
507{
508 paramIn(cp, "curTick", unserializedCurTick);
509}
510
511Serializable::Serializable()
512{
513}
514
515Serializable::~Serializable()
516{
517}
518
519void
520Serializable::serializeSection(CheckpointOut &cp, const char *name) const
521{
522 Serializable::ScopedCheckpointSection sec(cp, name);
523 serialize(cp);
524}
525
526void
527Serializable::serializeSectionOld(CheckpointOut &cp, const char *name)
528{
529 Serializable::ScopedCheckpointSection sec(cp, name);
530 serializeOld(cp);
531}
532
533void
534Serializable::unserializeSection(CheckpointIn &cp, const char *name)
535{
536 Serializable::ScopedCheckpointSection sec(cp, name);
537 unserialize(cp);
538}
539
540void
541Serializable::serializeAll(const string &cpt_dir)
542{
543 string dir = CheckpointIn::setDir(cpt_dir);
544 if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
545 fatal("couldn't mkdir %s\n", dir);
546
547 string cpt_file = dir + CheckpointIn::baseFilename;
548 ofstream outstream(cpt_file.c_str());
549 time_t t = time(NULL);
550 if (!outstream.is_open())
551 fatal("Unable to open file %s for writing\n", cpt_file.c_str());
552 outstream << "## checkpoint generated: " << ctime(&t);
553
554 globals.serializeSection(outstream, "Globals");
555
556 SimObject::serializeAll(outstream);
557}
558
559void
560Serializable::unserializeGlobals(CheckpointIn &cp)
561{
562 globals.unserializeSection(cp, "Globals");
563
564 for (uint32_t i = 0; i < numMainEventQueues; ++i)
565 mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
566}
567
568Serializable::ScopedCheckpointSection::~ScopedCheckpointSection()
569{
570 assert(!path.empty());
571 DPRINTF(Checkpoint, "Popping: %s\n", path.top());
572 path.pop();
573}
574
575void
576Serializable::ScopedCheckpointSection::pushName(const char *obj_name)
577{
578 if (path.empty()) {
579 path.push(obj_name);
580 } else {
581 path.push(csprintf("%s.%s", path.top(), obj_name));
582 }
583 DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
584}
585
586void
587Serializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
588{
589 DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
590 Serializable::currentSection());
591 cp << "\n[" << Serializable::currentSection() << "]\n";
592}
593
594void
595debug_serialize(const string &cpt_dir)
596{
597 Serializable::serializeAll(cpt_dir);
598}
599
600const std::string &
601Serializable::currentSection()
602{
603 assert(!path.empty());
604
605 return path.top();
606}
607
608const char *CheckpointIn::baseFilename = "m5.cpt";
609
610string CheckpointIn::currentDirectory;
611
612string
613CheckpointIn::setDir(const string &name)
614{
615 // use csprintf to insert curTick() into directory name if it
616 // appears to have a format placeholder in it.
617 currentDirectory = (name.find("%") != string::npos) ?
618 csprintf(name, curTick()) : name;
619 if (currentDirectory[currentDirectory.size() - 1] != '/')
620 currentDirectory += "/";
621 return currentDirectory;
622}
623
624string
625CheckpointIn::dir()
626{
627 return currentDirectory;
628}
629
630
631CheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
632 : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
633{
634 string filename = cptDir + "/" + CheckpointIn::baseFilename;
635 if (!db->load(filename)) {
636 fatal("Can't load checkpoint file '%s'\n", filename);
637 }
638}
639
640CheckpointIn::~CheckpointIn()
641{
642 delete db;
643}
644
645bool
646CheckpointIn::find(const string &section, const string &entry, string &value)
647{
648 return db->find(section, entry, value);
649}
650
651
652bool
653CheckpointIn::findObj(const string &section, const string &entry,
654 SimObject *&value)
655{
656 string path;
657
658 if (!db->find(section, entry, path))
659 return false;
660
661 value = objNameResolver.resolveSimObject(path);
662 return true;
663}
664
665
666bool
667CheckpointIn::sectionExists(const string &section)
668{
669 return db->sectionExists(section);
670}