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