diff --git a/sim/builder.cc b/sim/builder.cc index 890451ec4..fa5c113a7 100644 --- a/sim/builder.cc +++ b/sim/builder.cc @@ -43,7 +43,7 @@ SimObjectBuilder::SimObjectBuilder(const string &_configClass, const string &_instanceName, ConfigNode *_configNode, const string &_simObjClassName) - : ParamContext(_configClass, true), + : ParamContext(_configClass, NoAutoInit), instanceName(_instanceName), configNode(_configNode), simObjClassName(_simObjClassName) diff --git a/sim/param.cc b/sim/param.cc index 84ecbf8f9..d20be8d33 100644 --- a/sim/param.cc +++ b/sim/param.cc @@ -560,15 +560,27 @@ SimObjectBaseParam::parse(const string &s, vector&value) list *ParamContext::ctxList = NULL; -ParamContext::ParamContext(const string &_iniSection, bool noAutoParse) +ParamContext::ParamContext(const string &_iniSection, InitPhase _initPhase) : iniFilePtr(NULL), // initialized on call to parseParams() - iniSection(_iniSection), paramList(NULL) + iniSection(_iniSection), paramList(NULL), + initPhase(_initPhase) { - if (!noAutoParse) { + // Put this context on global list for initialization + if (initPhase != NoAutoInit) { if (ctxList == NULL) ctxList = new list(); - (*ctxList).push_back(this); + // keep list sorted by ascending initPhase values + list::iterator i = ctxList->begin(); + list::iterator end = ctxList->end(); + for (; i != end; ++i) { + if (initPhase <= (*i)->initPhase) { + // found where we want to insert + break; + } + } + // (fall through case: insert at end) + ctxList->insert(i, this); } } diff --git a/sim/param.hh b/sim/param.hh index fe13edc48..6706820c2 100644 --- a/sim/param.hh +++ b/sim/param.hh @@ -74,11 +74,30 @@ class ParamContext public: - // Second arg, if set to true, says don't put on paramContextList - // (i.e. don't automatically parse params). Used by derived - // SimObjectBuilder class, where parsing is done in - // SimObject::create() - ParamContext(const std::string &_iniSection, bool noAutoParse = false); + /// Initialization phases for ParamContext objects. + enum InitPhase { + NoAutoInit = -1, ///< Don't initialize at all... params + /// will be parsed later (used by + /// SimObjectBuilder, which parses + /// params in SimObject::create(). + OutputInitPhase = 0, ///< Output stream initialization + TraceInitPhase = 1, ///< Trace context initialization: + /// depends on output streams, but + /// needs to come before others so we + /// can use tracing in other + /// ParamContext init code + StatsInitPhase = 2, ///< Stats output initialization + DefaultInitPhase = 3 ///< Everything else + }; + + /// Records the initialization phase for this ParamContext. + InitPhase initPhase; + + /// Constructor. + /// @param _iniSection Name of .ini section corresponding to this context. + /// @param _initPhase Initialization phase (see InitPhase). + ParamContext(const std::string &_iniSection, + InitPhase _initPhase = DefaultInitPhase); virtual ~ParamContext() {} diff --git a/sim/universe.cc b/sim/universe.cc index ffff52104..824b985fa 100644 --- a/sim/universe.cc +++ b/sim/universe.cc @@ -56,7 +56,8 @@ ostream *configStream; class UniverseParamContext : public ParamContext { public: - UniverseParamContext(const string &is) : ParamContext(is) {} + UniverseParamContext(const string &is) + : ParamContext(is, OutputInitPhase) {} void checkParams(); };