Allow the fixwhite stuff to work when committing from a subdir
[gem5.git] / src / sim / param.hh
1 /*
2 * Copyright (c) 2002-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Steve Reinhardt
29 */
30
31 #ifndef __SIM_PARAM_HH__
32 #define __SIM_PARAM_HH__
33
34 #include <iostream>
35 #include <list>
36 #include <string>
37 #include <vector>
38
39 #include "sim/startup.hh"
40
41 // forward decls
42 class IniFile;
43 class BaseParam;
44 class SimObject;
45
46 //
47 // The context of a parameter definition... usually a subclass of
48 // SimObjectBuilder (which derives from ParamContext), but abstracted
49 // here to support more global simulator control parameters as well.
50 //
51 class ParamContext : protected StartupCallback
52 {
53 protected:
54
55 // .ini file (database) for parameter lookup... initialized on call
56 // to parseParams()
57 IniFile *iniFilePtr;
58
59 // .ini file section for parameter lookup
60 const std::string iniSection;
61
62 typedef std::vector<BaseParam *> ParamList;
63
64 // list of parameters defined in this context
65 ParamList *paramList;
66
67 ParamList *getParamList() {
68 if (!paramList)
69 paramList = new ParamList;
70 return paramList;
71 }
72
73 public:
74
75 /// Constructor.
76 /// @param _iniSection Name of .ini section corresponding to this context.
77 /// @param _initPhase Initialization phase (see InitPhase).
78 ParamContext(const std::string &_iniSection);
79 virtual ~ParamContext() {}
80
81 // add a parameter to the context... called from the parameter
82 // object's constructor (see BaseParam::BaseParam())
83 void addParam(BaseParam *);
84
85 // call parse() on all params in this context to convert string
86 // representations to parameter values
87 virtual void parseParams(IniFile &iniFile);
88
89 // Check parameter values for validity & consistency. Default
90 // implementation is no-op; derive subclass & override to add
91 // actual functionality here
92 virtual void checkParams();
93
94 // Clean up at end of execution: close file descriptors, etc.
95 // Default implementation is no-op; derive subclass & override to
96 // add actual functionality here
97 virtual void cleanup();
98
99 // dump parameter descriptions
100 void describeParams(std::ostream &);
101
102 // Display the parameters & values used
103 void showParams(std::ostream &);
104
105 // print context information for parameter error
106 virtual void printErrorProlog(std::ostream &);
107
108 // generate the name for this instance of this context (used as a
109 // prefix to create unique names in resolveSimObject()
110 virtual const std::string &getInstanceName() { return iniSection; }
111 };
112
113
114 //
115 // Base class for all parameter objects
116 //
117 class BaseParam
118 {
119 public:
120
121 ParamContext *context;
122 std::string name;
123 std::string description; // text description for help message
124 bool wasSet; // true if parameter was set by user
125 bool hasDefault; // true if parameter has default value
126
127 BaseParam(ParamContext *_context, const std::string &_name,
128 const std::string &_description, bool _hasDefault)
129 : context(_context), name(_name), description(_description),
130 wasSet(false), hasDefault(_hasDefault)
131 {
132 context->addParam(this);
133 }
134
135 virtual ~BaseParam() {}
136
137 // a parameter is valid only if its value was set by the user or
138 // it has a default value
139 bool isValid() const
140 {
141 return (wasSet || hasDefault);
142 }
143
144 // set value by parsing string
145 virtual void parse(const std::string &s) = 0;
146
147 // display value to stream
148 virtual void showValue(std::ostream &) const = 0;
149
150 // display type to stream
151 virtual void showType(std::ostream &) const = 0;
152
153 // signal parse or usage error
154 virtual void die(const std::string &err) const;
155 };
156
157 //
158 // Template classes to specialize parameters to specific types.
159 //
160 // Param<T> is for single-valued (scalar) parameters of type T.
161 // VectorParam<T> is for multi-valued (vector) parameters of type T.
162 // These are specified in the .ini file as a space-delimited list of
163 // arguments.
164 //
165 template <class T>
166 class Param : public BaseParam
167 {
168 protected:
169
170 T value;
171
172 public:
173
174 // Param with default value: set value to default
175 Param(ParamContext *context,
176 const std::string &name, const std::string &description, T dfltValue)
177 : BaseParam(context, name, description, true),
178 value(dfltValue)
179 {
180 }
181
182 // Param with no default value: leave value uninitialized
183 Param(ParamContext *context,
184 const std::string &name, const std::string &description)
185 : BaseParam(context, name, description, false)
186 {
187 }
188
189 virtual ~Param() {}
190
191 operator T&()
192 {
193 // if we attempt to reference an invalid parameter (i.e., one
194 // with no default value that was not set by the user), die.
195 if (!isValid())
196 die("not found");
197 return value;
198 }
199
200 T returnValue() const { return value; }
201
202 // display value to stream
203 virtual void showValue(std::ostream &os) const;
204
205 // display type to stream
206 virtual void showType(std::ostream &) const;
207
208 // set value by parsing string
209 virtual void parse(const std::string &s);
210 };
211
212
213 //
214 // Template class for vector-valued parameters (lists)
215 //
216 template <class T>
217 class VectorParam : public BaseParam
218 {
219 protected:
220
221 std::vector<T> value;
222
223 public:
224
225 typedef typename std::vector<T>::size_type size_type;
226
227 // Param with default value: set value to default
228 VectorParam(ParamContext *context, const std::string &name,
229 const std::string &description,
230 const std::vector<T> &dfltValue)
231 : BaseParam(context, name, description, true),
232 value(dfltValue)
233 {
234 }
235
236 // Param with no default value: leave value uninitialized
237 VectorParam(ParamContext *context,
238 const std::string &name, const std::string &description)
239 : BaseParam(context, name, description, false)
240 {
241 }
242
243 virtual ~VectorParam() {}
244
245 // basic vector access methods
246 size_type size() const
247 {
248 if (!isValid())
249 die("not found");
250 return value.size();
251 }
252
253 const T &operator[](size_type n) const
254 {
255 if (!isValid())
256 die("not found");
257 return value[n];
258 }
259
260 // return reference to value vector
261 operator std::vector<T>&()
262 {
263 if (!isValid())
264 die("not found");
265 return value;
266 }
267
268 // display value to stream
269 virtual void showValue(std::ostream &os) const;
270
271 // display type to stream
272 virtual void showType(std::ostream &) const;
273
274 // set value by parsing string
275 virtual void parse(const std::string &s);
276 };
277
278 //
279 // Specialization of Param<int> and VectorParam<int> to handle
280 // enumerated types is done in two ways, using SimpleEnumParam and
281 // MappedEnumParam (and their vector counterparts,
282 // SimpleEnumVectorParam and MappedEnumVectorParam). SimpleEnumParam
283 // takes an array of strings and maps them to integers based on array
284 // index. MappedEnumParam takes an array of string-to-int mappings,
285 // allowing for mapping strings to non-contiguous integer values, or
286 // mapping multiple strings to the same integer value.
287 //
288 // Both SimpleEnumParam and MappedEnumParam are implemented using a
289 // single template class, EnumParam<Map>, which takes the type of the map
290 // as a parameter (const char * or EnumParamMap). Similarly,
291 // SimpleEnumVectorParam and MappedEnumVectorParam are both
292 // implemented using EnumVectorParam<Map>.
293 //
294 template <class Map>
295 class EnumParam : public Param<int>
296 {
297 const int num_values;
298 const Map *map;
299
300 public:
301
302 // Param with default value: set value to default
303 EnumParam(ParamContext *context,
304 const std::string &name, const std::string &description,
305 const Map *_map, int _num_values,
306 int dfltValue)
307 : Param<int>(context, name, description, dfltValue),
308 num_values(_num_values), map(_map)
309 {
310 }
311
312 // Param with no default value: leave value uninitialized
313 EnumParam(ParamContext *context,
314 const std::string &name, const std::string &description,
315 const Map *_map, int _num_values)
316 : Param<int>(context, name, description),
317 num_values(_num_values), map(_map)
318 {
319 }
320
321 virtual ~EnumParam() {}
322
323 // display value to stream
324 virtual void showValue(std::ostream &os) const;
325
326 // display type to stream
327 virtual void showType(std::ostream &) const;
328
329 // set value by parsing string
330 virtual void parse(const std::string &s);
331 };
332
333 //
334 // Vector counterpart to SimpleEnumParam
335 //
336 template <class Map>
337 class EnumVectorParam : public VectorParam<int>
338 {
339 const int num_values;
340 const Map *map;
341
342 public:
343
344 // Param with default value: set value to default
345 EnumVectorParam(ParamContext *context,
346 const std::string &name, const std::string &description,
347 const Map *_map, int _num_values,
348 std::vector<int> &dfltValue)
349 : VectorParam<int>(context, name, description, dfltValue),
350 num_values(_num_values), map(_map)
351 {
352 }
353
354 // Param with no default value: leave value uninitialized
355 EnumVectorParam(ParamContext *context,
356 const std::string &name, const std::string &description,
357 const Map *_map, int _num_values)
358 : VectorParam<int>(context, name, description),
359 num_values(_num_values), map(_map)
360 {
361 }
362
363 virtual ~EnumVectorParam() {}
364
365 // display value to stream
366 virtual void showValue(std::ostream &os) const;
367
368 // display type to stream
369 virtual void showType(std::ostream &) const;
370
371 // set value by parsing string
372 virtual void parse(const std::string &s);
373 };
374
375 // Specialize EnumParam for a particular enumeration type ENUM
376 // (automates casting to get value of enum type)
377
378 template <class ENUM>
379 class SimpleEnumParam : public EnumParam<const char *>
380 {
381 public:
382
383 SimpleEnumParam(ParamContext *context,
384 const std::string &name, const std::string &description,
385 const char **_map, int _num_values,
386 ENUM dfltValue)
387 : EnumParam<const char *>(context, name, description,
388 _map, _num_values, (int)dfltValue)
389 {
390 }
391
392 SimpleEnumParam(ParamContext *context,
393 const std::string &name, const std::string &description,
394 const char **_map, int _num_values)
395 : EnumParam<const char *>(context, name, description,
396 _map, _num_values)
397 {
398 }
399
400 operator ENUM() const
401 {
402 if (!isValid())
403 die("not found");
404 return (ENUM)value;
405 }
406 };
407
408
409 // Specialize EnumParam for a particular enumeration type ENUM
410 // (automates casting to get value of enum type)
411
412 template <class ENUM>
413 class SimpleEnumVectorParam : public EnumVectorParam<const char *>
414 {
415 public:
416
417 // skip default value constructor: too much pain to convert
418 // vector<ENUM> initializer to vector<int>
419
420
421 SimpleEnumVectorParam(ParamContext *context,
422 const std::string &name,
423 const std::string &description,
424 const char **_map, int _num_values)
425 : EnumVectorParam<const char *>(context, name, description,
426 _map, _num_values)
427 {
428 }
429
430 ENUM operator[](size_type n)
431 {
432 if (!isValid())
433 die("not found");
434 return (ENUM)value[n];
435 }
436 };
437
438
439 //
440 // Handle enums via string-to-int map (see comment above).
441 //
442
443 // An array of string-to-int mappings must be supplied using the
444 // following type.
445 typedef struct {
446 const char *name;
447 int value;
448 } EnumParamMap;
449
450 // Specialize EnumParam for a particular enumeration type ENUM
451 // (automates casting to get value of enum type)
452
453 template <class ENUM>
454 class MappedEnumParam : public EnumParam<EnumParamMap>
455 {
456 public:
457
458 MappedEnumParam(ParamContext *context,
459 const std::string &name, const std::string &description,
460 const EnumParamMap *_map, int _num_values,
461 ENUM dfltValue)
462 : EnumParam<EnumParamMap>(context, name, description,
463 _map, _num_values, (int)dfltValue)
464 {
465 }
466
467 MappedEnumParam(ParamContext *context,
468 const std::string &name, const std::string &description,
469 const EnumParamMap *_map, int _num_values)
470 : EnumParam<EnumParamMap>(context, name, description,
471 _map, _num_values)
472 {
473 }
474
475 operator ENUM()
476 {
477 if (!isValid())
478 die("not found");
479 return (ENUM)value[this->n];
480 }
481 };
482
483
484 // Specialize EnumParam for a particular enumeration type ENUM
485 // (automates casting to get value of enum type)
486
487 template <class ENUM>
488 class MappedEnumVectorParam : public EnumVectorParam<EnumParamMap>
489 {
490 public:
491
492 // skip default value constructor: too much pain to convert
493 // vector<ENUM> initializer to vector<int>
494
495
496 MappedEnumVectorParam(ParamContext *context,
497 const std::string &name,
498 const std::string &description,
499 const EnumParamMap *_map, int _num_values)
500 : EnumVectorParam<EnumParamMap>(context, name, description,
501 _map, _num_values)
502 {
503 }
504
505 ENUM operator[](size_type n)
506 {
507 if (!isValid())
508 die("not found");
509 return (ENUM)value[n];
510 }
511 };
512
513
514 //
515 // Parameters that point to other simulation objects (e.g. caches,
516 // busses, etc.) are handled by specializing SimObjectBaseParam to the
517 // specific subtype. The main purpose of SimObjectBaseParam is to
518 // provide a place to stick several helper functions common to all
519 // SimObject-derived parameters.
520 //
521 class SimObjectBaseParam : public BaseParam
522 {
523 public:
524
525 SimObjectBaseParam(ParamContext *context, const std::string &name,
526 const std::string &description, bool hasDefault)
527 : BaseParam(context, name, description, hasDefault)
528 {
529 }
530
531 virtual ~SimObjectBaseParam() {}
532
533 // helper function for SimObjectParam<T>::showValue()
534 void showValue(std::ostream &os, SimObject *obj) const;
535
536 // helper function for SimObjectParam<T>::parse()
537 void parse(const std::string &s, SimObject *&value);
538
539 // helper function for SimObjectParam<T>::parse()
540 void parse(const std::string &s, std::vector<SimObject *>&value_vec);
541 };
542
543
544 //
545 // Parameter to a specific type of SimObject. Note that T must be a
546 // pointer to a class derived from SimObject (e.g., <CPU *>).
547 //
548
549 template <class T> class SimObjectParam;
550
551 template <class T>
552 class SimObjectParam<T *> : public SimObjectBaseParam
553 {
554 protected:
555
556 T *value;
557
558 public:
559
560 // initialization w/o default
561 SimObjectParam(ParamContext *context,
562 const std::string &name, const std::string &description)
563 : SimObjectBaseParam(context, name, description, false)
564 {
565 }
566
567 // initialization wit=h default
568 SimObjectParam(ParamContext *context,
569 const std::string &name, const std::string &description,
570 T *dfltValue)
571 : SimObjectBaseParam(context, name, description, true),
572 value(dfltValue)
573 {
574 }
575
576 virtual ~SimObjectParam() {}
577
578 // convert to pointer
579 operator T*()
580 {
581 if (!isValid())
582 die("not found");
583 return value;
584 }
585
586 T *operator->() const
587 {
588 if (!isValid())
589 die("not found");
590 return value;
591 }
592
593 // display value to stream
594 virtual void showValue(std::ostream &os) const
595 {
596 SimObjectBaseParam::showValue(os, value);
597 }
598
599 // display type to stream: see REGISTER_SIM_OBJECT macro in
600 // sim_object.hh for declaration
601 virtual void showType(std::ostream &os) const;
602
603 // set value by parsing string
604 virtual void parse(const std::string &s)
605 {
606 SimObject *so_ptr;
607 // first parse to generic SimObject *
608 SimObjectBaseParam::parse(s, so_ptr);
609 // now dynamic_cast to specific derived type
610 value = dynamic_cast<T *>(so_ptr);
611 // check for failure of dynamic_cast
612 if (value == NULL && so_ptr != NULL)
613 die("not of appropriate type");
614 }
615 };
616
617
618 //
619 // Vector counterpart to SimObjectParam<T>
620 //
621
622 template <class T> class SimObjectVectorParam;
623
624 template <class T>
625 class SimObjectVectorParam<T *> : public SimObjectBaseParam
626 {
627 protected:
628
629 std::vector<T *> value;
630
631 public:
632
633 typedef typename std::vector<T *>::size_type size_type;
634
635 SimObjectVectorParam(ParamContext *context,
636 const std::string &name,
637 const std::string &description)
638 : SimObjectBaseParam(context, name, description, false)
639 {
640 }
641
642 SimObjectVectorParam(ParamContext *context,
643 const std::string &name,
644 const std::string &description,
645 std::vector<T *> dfltValue)
646 : SimObjectBaseParam(context, name, description, true),
647 value(dfltValue)
648 {
649 }
650
651 virtual ~SimObjectVectorParam() {}
652
653 // basic vector access methods
654 size_type size() const
655 {
656 if (!isValid())
657 die("not found");
658 return value.size();
659 }
660
661 T *&operator[](size_type n)
662 {
663 if (!isValid())
664 die("not found");
665 return value[n];
666 }
667
668 // return reference to value vector
669 operator std::vector<T *>&()
670 {
671 if (!isValid())
672 die("not found");
673 return value;
674 }
675
676 // display value to stream
677 virtual void showValue(std::ostream &os) const
678 {
679 for (int i = 0; i < value.size(); i++) {
680 if (i != 0)
681 os << " ";
682 SimObjectBaseParam::showValue(os, value[i]);
683 }
684 }
685
686 // display type to stream: see
687 virtual void showType(std::ostream &os) const;
688
689 // set value by parsing string
690 virtual void parse(const std::string &s)
691 {
692 std::vector<SimObject *> so_ptr_vec;
693 // first parse to generic SimObject * vector (from SimObjectBaseParam)
694 SimObjectBaseParam::parse(s, so_ptr_vec);
695
696 value.resize(so_ptr_vec.size());
697
698 for (int i = 0; i < so_ptr_vec.size(); ++i) {
699 // now dynamic_cast to specific derived type
700 value[i] = dynamic_cast<T *>(so_ptr_vec[i]);
701 // check for failure of dynamic_cast
702 if (value[i] == NULL && so_ptr_vec[i] != NULL)
703 die("not of appropriate type");
704 }
705 }
706 };
707
708 //
709 // Macro to define showType() methods for SimObjectParam &
710 // SimObjectVectorParam. Can't do this automatically as it requires a
711 // string name for the type, which you can't get from a template
712 // argument. For concrete derived SimObject types, this macro is
713 // automatically invoked by REGISTER_SIM_OBJECT() (see sim_object.hh).
714 //
715 #define DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS) \
716 template<> \
717 void \
718 SimObjectParam<OBJ_CLASS *>::showType(std::ostream &os) const \
719 { \
720 os << CLASS_NAME; \
721 } \
722 \
723 template<> \
724 void \
725 SimObjectVectorParam<OBJ_CLASS *>::showType(std::ostream &os) const \
726 { \
727 os << "vector of " << CLASS_NAME; \
728 }
729
730
731 //
732 // Declarations for low-level parsing & displaying functions. These
733 // are used internally, but should not be used directly by clients of
734 // the parameter mechanism, but are declared here so they can be
735 // shared with the serialization code (see sim/serialize.cc).
736 template <class T> bool parseParam(const std::string &str, T &data);
737 template <class T> void showParam(std::ostream &os, const T &data);
738
739 void parseTime(const std::vector<int> &time, struct tm *tm);
740 #endif // _SIM_PARAM_HH_