diff --git a/dev/etherdump.cc b/dev/etherdump.cc index 27817d456..485d5599c 100644 --- a/dev/etherdump.cc +++ b/dev/etherdump.cc @@ -42,11 +42,9 @@ using std::string; -EtherDump::EtherDump(const string &name, const string &file, int max) - : SimObject(name), maxlen(max) +EtherDump::EtherDump(const string &name, std::ostream *_stream, int max) + : SimObject(name), stream(_stream), maxlen(max) { - if (!file.empty()) - stream.open(file.c_str()); } #define DLT_EN10MB 1 // Ethernet (10Mb) @@ -74,9 +72,6 @@ struct pcap_pkthdr { void EtherDump::init() { - if (!stream.is_open()) - return; - curtime = time(NULL); s_freq = ticksPerSecond; us_freq = ticksPerSecond / ULL(1000000); @@ -91,7 +86,7 @@ EtherDump::init() hdr.sigfigs = 0; hdr.linktype = DLT_EN10MB; - stream.write(reinterpret_cast(&hdr), sizeof(hdr)); + stream->write(reinterpret_cast(&hdr), sizeof(hdr)); /* * output an empty packet with the current time so that we know @@ -103,9 +98,9 @@ EtherDump::init() pkthdr.microseconds = 0; pkthdr.caplen = 0; pkthdr.len = 0; - stream.write(reinterpret_cast(&pkthdr), sizeof(pkthdr)); + stream->write(reinterpret_cast(&pkthdr), sizeof(pkthdr)); - stream.flush(); + stream->flush(); } void @@ -116,9 +111,9 @@ EtherDump::dumpPacket(PacketPtr &packet) pkthdr.microseconds = (curTick / us_freq) % ULL(1000000); pkthdr.caplen = std::min(packet->length, maxlen); pkthdr.len = packet->length; - stream.write(reinterpret_cast(&pkthdr), sizeof(pkthdr)); - stream.write(reinterpret_cast(packet->data), pkthdr.caplen); - stream.flush(); + stream->write(reinterpret_cast(&pkthdr), sizeof(pkthdr)); + stream->write(reinterpret_cast(packet->data), pkthdr.caplen); + stream->flush(); } BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDump) @@ -130,28 +125,14 @@ END_DECLARE_SIM_OBJECT_PARAMS(EtherDump) BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDump) - INIT_PARAM(file, "file to dump packets to"), + INIT_PARAM_DFLT(file, "file to dump packets to", "etherdump"), INIT_PARAM_DFLT(maxlen, "max portion of packet data to dump", 96) END_INIT_SIM_OBJECT_PARAMS(EtherDump) CREATE_SIM_OBJECT(EtherDump) { - string filename; - if (file.isValid()) { - filename = file; - - if (filename[0] != '/' && !outputDirectory.empty()) - filename = outputDirectory + filename; - } else { - if (outputDirectory.empty()) { - filename = "etherdump"; - } else { - filename = outputDirectory + "etherdump"; - } - } - - return new EtherDump(getInstanceName(), filename, maxlen); + return new EtherDump(getInstanceName(), makeOutputStream(file), maxlen); } REGISTER_SIM_OBJECT("EtherDump", EtherDump) diff --git a/dev/etherdump.hh b/dev/etherdump.hh index 62364359e..b127d05e2 100644 --- a/dev/etherdump.hh +++ b/dev/etherdump.hh @@ -43,7 +43,7 @@ class EtherDump : public SimObject { private: - std::ofstream stream; + std::ostream *stream; const int maxlen; void dumpPacket(PacketPtr &packet); void init(); @@ -53,9 +53,9 @@ class EtherDump : public SimObject Tick us_freq; public: - EtherDump(const std::string &name, const std::string &file, int max); + EtherDump(const std::string &name, std::ostream *_stream, int max); - inline void dump(PacketPtr &pkt) { if (stream.is_open()) dumpPacket(pkt); } + inline void dump(PacketPtr &pkt) { dumpPacket(pkt); } }; #endif // __ETHERDUMP_H__ diff --git a/dev/simconsole.cc b/dev/simconsole.cc index a15057402..b2afb3f84 100644 --- a/dev/simconsole.cc +++ b/dev/simconsole.cc @@ -72,27 +72,22 @@ SimConsole::Event::process(int revent) cons->detach(); } -SimConsole::SimConsole(const string &name, const string &file, int num) +SimConsole::SimConsole(const string &name, std::ostream *os, int num) : SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1), - listener(NULL), txbuf(16384), rxbuf(16384), outfile(NULL) + listener(NULL), txbuf(16384), rxbuf(16384), outfile(os) #if TRACING_ON == 1 , linebuf(16384) #endif { - if (!file.empty()) - outfile = new ofstream(file.c_str()); - if (outfile) outfile->setf(ios::unitbuf); - } SimConsole::~SimConsole() { close(); - if (outfile) - delete outfile; + closeOutputStream(outfile); } void @@ -311,7 +306,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimConsole) INIT_PARAM(listener, "console listener"), INIT_PARAM(intr_control, "interrupt controller"), - INIT_PARAM_DFLT(output, "file to dump output to", ""), + INIT_PARAM(output, "file to dump output to"), INIT_PARAM_DFLT(append_name, "append name() to filename", true), INIT_PARAM_DFLT(number, "console number", 0) @@ -319,18 +314,18 @@ END_INIT_SIM_OBJECT_PARAMS(SimConsole) CREATE_SIM_OBJECT(SimConsole) { - string filename = output; - if (filename.empty()) { - if (!outputDirectory.empty()) - filename = outputDirectory + getInstanceName(); + string filename; + + if (!output.isValid()) { + filename = getInstanceName(); + } else if (append_name) { + filename = (string)output + "." + getInstanceName(); } else { - if (append_name) - filename += "." + getInstanceName(); - if (!outputDirectory.empty()) - filename = outputDirectory + filename; + filename = output; } - SimConsole *console = new SimConsole(getInstanceName(), filename, number); + SimConsole *console = new SimConsole(getInstanceName(), + makeOutputStream(filename), number); ((ConsoleListener *)listener)->add(console); return console; diff --git a/dev/simconsole.hh b/dev/simconsole.hh index 138e2e36a..c5a281834 100644 --- a/dev/simconsole.hh +++ b/dev/simconsole.hh @@ -70,7 +70,7 @@ class SimConsole : public SimObject ConsoleListener *listener; public: - SimConsole(const std::string &name, const std::string &file, int num); + SimConsole(const std::string &name, std::ostream *os, int num); ~SimConsole(); protected: diff --git a/sim/builder.cc b/sim/builder.cc index 53e5cf3d8..890451ec4 100644 --- a/sim/builder.cc +++ b/sim/builder.cc @@ -39,26 +39,6 @@ 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, @@ -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..0147ffcc3 100644 --- a/sim/main.cc +++ b/sim/main.cc @@ -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/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/universe.cc b/sim/universe.cc index 79e32098c..ffff52104 100644 --- a/sim/universe.cc +++ b/sim/universe.cc @@ -51,12 +51,10 @@ double __ticksPerPS; string outputDirectory; ostream *outputStream; +ostream *configStream; class UniverseParamContext : public ParamContext { - private: - ofstream outputFile; - public: UniverseParamContext(const string &is) : ParamContext(is) {} void checkParams(); @@ -68,9 +66,14 @@ Param universe_freq(&universe, "frequency", "tick frequency", 200000000); Param universe_output_dir(&universe, "output_dir", - "directory to output data to"); + "directory to output data to", + "."); Param universe_output_file(&universe, "output_file", - "file to dump simulator output to"); + "file to dump simulator output to", + "cout"); +Param universe_config_output_file(&universe, "config_output_file", + "file to dump simulator config to", + "m5config.out"); void UniverseParamContext::checkParams() @@ -97,26 +100,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"; - } - - 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; - } + outputStream = makeOutputStream(universe_output_file); + configStream = universe_config_output_file.isValid() + ? makeOutputStream(universe_config_output_file) + : outputStream; } + + +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(os); + if (ofs) + ofs->close(); +} + + +