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