summaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/builder.cc30
-rw-r--r--sim/builder.hh3
-rw-r--r--sim/main.cc4
-rw-r--r--sim/param.cc20
-rw-r--r--sim/param.hh29
-rw-r--r--sim/process.cc12
-rw-r--r--sim/serialize.cc5
-rw-r--r--sim/system.cc4
-rw-r--r--sim/universe.cc81
9 files changed, 108 insertions, 80 deletions
diff --git a/sim/builder.cc b/sim/builder.cc
index 53e5cf3d8..fa5c113a7 100644
--- a/sim/builder.cc
+++ b/sim/builder.cc
@@ -39,31 +39,11 @@
using namespace std;
-
-ostream &
-builderStream()
-{
- static ofstream file;
- static ostream *stream = NULL;
-
- if (!stream) {
- if (!outputDirectory.empty()) {
- string filename = outputDirectory + "builder.txt";
- file.open(filename.c_str());
- stream = &file;
- } else {
- stream = outputStream;
- }
- }
-
- return *stream;
-}
-
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)
@@ -187,10 +167,10 @@ SimObjectClass::createObject(IniFile &configDB,
// echo object parameters to stats file (for documenting the
// config used to generate the associated stats)
- builderStream() << "[" << object->name() << "]" << endl;
- builderStream() << "type=" << simObjClassName << endl;
- objectBuilder->showParams(builderStream());
- builderStream() << endl;
+ *configStream << "[" << object->name() << "]" << endl;
+ *configStream << "type=" << simObjClassName << endl;
+ objectBuilder->showParams(*configStream);
+ *configStream << endl;
// done with the SimObjectBuilder now
delete objectBuilder;
diff --git a/sim/builder.hh b/sim/builder.hh
index a85c88b76..36e40c2a9 100644
--- a/sim/builder.hh
+++ b/sim/builder.hh
@@ -38,9 +38,6 @@
class SimObject;
-std::ostream &
-builderStream();
-
//
// A SimObjectBuilder serves as an evaluation context for a set of
// parameters that describe a specific instance of a SimObject. This
diff --git a/sim/main.cc b/sim/main.cc
index 2a0427303..76507bbd8 100644
--- a/sim/main.cc
+++ b/sim/main.cc
@@ -111,7 +111,7 @@ static void
showBriefHelp(ostream &out)
{
out << "Usage: " << myProgName
- << " [-hn] [-Dname[=def]] [-Uname] [-I[dir]] "
+ << " [-hnu] [-Dname[=def]] [-Uname] [-I[dir]] "
<< "[--<section>:<param>=<value>] [<config file> ...]" << endl
<< " -h: print long help (including parameter listing)" << endl
<< " -n: don't load default.ini" << endl
@@ -396,7 +396,7 @@ main(int argc, char **argv)
// Echo command line and all parameter settings to stats file as well.
echoCommandLine(argc, argv, *outputStream);
- ParamContext::showAllContexts(builderStream());
+ ParamContext::showAllContexts(*configStream);
// Now process the configuration hierarchy and create the SimObjects.
ConfigHierarchy configHierarchy(simConfigDB);
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<SimObject *>&value)
list<ParamContext *> *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<ParamContext *>();
- (*ctxList).push_back(this);
+ // keep list sorted by ascending initPhase values
+ list<ParamContext *>::iterator i = ctxList->begin();
+ list<ParamContext *>::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/process.cc b/sim/process.cc
index b4febc75b..98db1f2e0 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -392,14 +392,10 @@ CREATE_SIM_OBJECT(LiveProcess)
// dummy for default env
vector<string> null_vec;
- // We do this with "temp" because of the bogus compiler warning
- // you get with g++ 2.95 -O if you just "return new LiveProcess(..."
- LiveProcess *temp = LiveProcess::create(getInstanceName(),
- stdin_fd, stdout_fd, stderr_fd,
- cmd,
- env.isValid() ? env : null_vec);
-
- return temp;
+ return LiveProcess::create(getInstanceName(),
+ stdin_fd, stdout_fd, stderr_fd,
+ cmd,
+ env.isValid() ? env : null_vec);
}
diff --git a/sim/serialize.cc b/sim/serialize.cc
index 91548f653..2a5e3d398 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -335,10 +335,7 @@ SerializeParamContext::checkParams()
if (serialize_dir.isValid()) {
checkpointDirBase = serialize_dir;
} else {
- if (outputDirectory.empty())
- checkpointDirBase = "m5.%012d";
- else
- checkpointDirBase = outputDirectory + "cpt.%012d";
+ checkpointDirBase = outputDirectory + "cpt.%012d";
}
// guarantee that directory ends with a '/'
diff --git a/sim/system.cc b/sim/system.cc
index f8312e33b..9fdadf649 100644
--- a/sim/system.cc
+++ b/sim/system.cc
@@ -156,8 +156,8 @@ System::System(Params *p)
if (!hwrpb)
panic("could not translate hwrpb addr\n");
- *(uint64_t*)(hwrpb+0x50) = params->system_type;
- *(uint64_t*)(hwrpb+0x58) = params->system_rev;
+ *(uint64_t*)(hwrpb+0x50) = htoa(params->system_type);
+ *(uint64_t*)(hwrpb+0x58) = htoa(params->system_rev);
} else
panic("could not find hwrpb\n");
diff --git a/sim/universe.cc b/sim/universe.cc
index 79e32098c..824b985fa 100644
--- a/sim/universe.cc
+++ b/sim/universe.cc
@@ -51,14 +51,13 @@ double __ticksPerPS;
string outputDirectory;
ostream *outputStream;
+ostream *configStream;
class UniverseParamContext : public ParamContext
{
- private:
- ofstream outputFile;
-
public:
- UniverseParamContext(const string &is) : ParamContext(is) {}
+ UniverseParamContext(const string &is)
+ : ParamContext(is, OutputInitPhase) {}
void checkParams();
};
@@ -68,9 +67,14 @@ Param<Tick> universe_freq(&universe, "frequency", "tick frequency",
200000000);
Param<string> universe_output_dir(&universe, "output_dir",
- "directory to output data to");
+ "directory to output data to",
+ ".");
Param<string> universe_output_file(&universe, "output_file",
- "file to dump simulator output to");
+ "file to dump simulator output to",
+ "cout");
+Param<string> universe_config_output_file(&universe, "config_output_file",
+ "file to dump simulator config to",
+ "m5config.out");
void
UniverseParamContext::checkParams()
@@ -97,26 +101,49 @@ UniverseParamContext::checkParams()
}
}
- string filename;
- if (universe_output_file.isValid()) {
- string f = universe_output_file;
- if (f != "stdout" && f != "cout" && f != "stderr" && f != "cerr")
- filename = outputDirectory + f;
- else
- filename = f;
- } else {
- if (outputDirectory.empty())
- filename = "stdout";
- else
- filename = outputDirectory + "output.txt";
- }
+ outputStream = makeOutputStream(universe_output_file);
+ configStream = universe_config_output_file.isValid()
+ ? makeOutputStream(universe_config_output_file)
+ : outputStream;
+}
- if (filename == "stdout" || filename == "cout")
- outputStream = &cout;
- else if (filename == "stderr" || filename == "cerr")
- outputStream = &cerr;
- else {
- outputFile.open(filename.c_str(), ios::trunc);
- outputStream = &outputFile;
- }
+
+std::ostream *
+makeOutputStream(std::string &name)
+{
+ if (name == "cerr" || name == "stderr")
+ return &std::cerr;
+
+ if (name == "cout" || name == "stdout")
+ return &std::cout;
+
+ string path = (name[0] != '/') ? outputDirectory + name : name;
+
+ // have to dynamically allocate a stream since we're going to
+ // return it... though the caller can't easily free it since it
+ // may be cerr or cout. need GC!
+ ofstream *s = new ofstream(path.c_str(), ios::trunc);
+
+ if (!s->is_open())
+ fatal("Cannot open file %s", path);
+
+ return s;
}
+
+
+void
+closeOutputStream(std::ostream *os)
+{
+ // can't close cerr or cout
+ if (os == &std::cerr || os == &std::cout)
+ return;
+
+ // can only close ofstreams, not generic ostreams, so try to
+ // downcast and close only if the downcast succeeds
+ std::ofstream *ofs = dynamic_cast<std::ofstream *>(os);
+ if (ofs)
+ ofs->close();
+}
+
+
+