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