summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/isa_desc6
-rw-r--r--base/cprintf.cc26
-rw-r--r--base/cprintf.hh1
-rw-r--r--base/loader/elf_object.cc6
-rw-r--r--base/misc.cc40
-rw-r--r--base/statistics.cc57
-rw-r--r--base/trace.cc7
-rw-r--r--cpu/simple_cpu/simple_cpu.cc6
-rw-r--r--dev/alpha_console.cc2
-rw-r--r--dev/console.cc59
-rw-r--r--dev/console.hh8
-rw-r--r--dev/etherdump.cc18
-rw-r--r--kern/tru64/tru64_system.cc6
-rw-r--r--sim/builder.cc45
-rw-r--r--sim/builder.hh19
-rw-r--r--sim/main.cc10
-rw-r--r--sim/serialize.cc18
-rw-r--r--sim/universe.cc55
-rw-r--r--test/stattest.cc6
19 files changed, 293 insertions, 102 deletions
diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc
index f0a4699f4..3533da09f 100644
--- a/arch/alpha/isa_desc
+++ b/arch/alpha/isa_desc
@@ -538,7 +538,7 @@ declare {{
trappingMode((enum TrappingMode)FP_TRAPMODE)
{
if (trappingMode != Imprecise) {
- warn("Warning: precise FP traps unimplemented\n");
+ warn("precise FP traps unimplemented\n");
}
}
@@ -1609,7 +1609,7 @@ declare {{
Trace::InstRecord *traceData)
{
if (!warned) {
- warn("Warning: instruction '%s' unimplemented\n", mnemonic);
+ warn("instruction '%s' unimplemented\n", mnemonic);
warned = true;
}
@@ -1620,7 +1620,7 @@ declare {{
Trace::InstRecord *traceData)
{
if (!xc->spec_mode && !warned) {
- warn("Warning: instruction '%s' unimplemented\n", mnemonic);
+ warn("instruction '%s' unimplemented\n", mnemonic);
warned = true;
}
diff --git a/base/cprintf.cc b/base/cprintf.cc
index 5796a712b..5cbf0c057 100644
--- a/base/cprintf.cc
+++ b/base/cprintf.cc
@@ -37,9 +37,20 @@ using namespace std;
namespace cp {
+ArgList::~ArgList()
+{
+ while (!objects.empty()) {
+ delete objects.front();
+ objects.pop_front();
+ }
+}
+
void
ArgList::dump(const string &format)
{
+ list_t::iterator iter = objects.begin();
+ list_t::iterator end = objects.end();
+
const char *p = format.c_str();
stream->fill(' ');
@@ -198,22 +209,19 @@ ArgList::dump(const string &format)
}
}
- if (!objects.empty())
+ if (iter != end)
{
- Base *data = objects.front();
- objects.pop_front();
-
ios::fmtflags saved_flags = stream->flags();
char old_fill = stream->fill();
int old_precision = stream->precision();
- data->process(*stream, fmt);
+ (*iter)->process(*stream, fmt);
stream->flags(saved_flags);
stream->fill(old_fill);
stream->precision(old_precision);
- delete data;
+ ++iter;
} else {
*stream << "<missing arg for format>";
}
@@ -241,11 +249,9 @@ ArgList::dump(const string &format)
}
}
- while (!objects.empty()) {
+ while (iter != end) {
*stream << "<extra arg>";
- Base *data = objects.front();
- objects.pop_front();
- delete data;
+ ++iter;
}
}
diff --git a/base/cprintf.hh b/base/cprintf.hh
index ac34cd252..ca5c08b16 100644
--- a/base/cprintf.hh
+++ b/base/cprintf.hh
@@ -89,6 +89,7 @@ class ArgList
public:
ArgList() : stream(&std::cout) {}
+ ~ArgList();
template<class T>
void append(const T &data) {
diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc
index 929d455a5..9889b9d4c 100644
--- a/base/loader/elf_object.cc
+++ b/base/loader/elf_object.cc
@@ -30,7 +30,11 @@
// Because of the -Wundef flag we have to do this
#define __LIBELF_INTERNAL__ 0
-#define __LIBELF64_LINUX 1
+// counterintuitive, but the flag below causes libelf to define
+// 64-bit elf types that apparently didn't exist in some older
+// versions of Linux. They seem to be there in 2.4.x, so don't
+// set this now (it causes things to break on 64-bit platforms).
+#define __LIBELF64_LINUX 0
#define __LIBELF_NEED_LINK_H 0
#include <libelf/libelf.h>
diff --git a/base/misc.cc b/base/misc.cc
index 8190caddd..5caf96d40 100644
--- a/base/misc.cc
+++ b/base/misc.cc
@@ -42,7 +42,17 @@ void
__panic(const string &format, cp::ArgList &args, const char *func,
const char *file, int line)
{
- string fmt = "panic: " + format + " @ cycle %d\n[%s:%s, line %d]\n";
+ string fmt = "panic: " + format;
+ switch (fmt[fmt.size() - 1]) {
+ case '\n':
+ case '\r':
+ break;
+ default:
+ fmt += "\n";
+ }
+
+ fmt += " @ cycle %d\n[%s:%s, line %d]\n";
+
args.append(curTick);
args.append(func);
args.append(file);
@@ -63,8 +73,18 @@ void
__fatal(const string &format, cp::ArgList &args, const char *func,
const char *file, int line)
{
- string fmt = "fatal: " + format + " @ cycle %d\n[%s:%s, line %d]\n"
- "Memory Usage: %ld KBytes\n";
+ string fmt = "fatal: " + format;
+
+ switch (fmt[fmt.size() - 1]) {
+ case '\n':
+ case '\r':
+ break;
+ default:
+ fmt += "\n";
+ }
+
+ fmt += " @ cycle %d\n[%s:%s, line %d]\n";
+ fmt += "Memory Usage: %ld KBytes\n";
args.append(curTick);
args.append(func);
@@ -83,16 +103,26 @@ __warn(const string &format, cp::ArgList &args, const char *func,
const char *file, int line)
{
string fmt = "warn: " + format;
+
+ switch (fmt[fmt.size() - 1]) {
+ case '\n':
+ case '\r':
+ break;
+ default:
+ fmt += "\n";
+ }
+
#ifdef VERBOSE_WARN
fmt += " @ cycle %d\n[%s:%s, line %d]\n";
args.append(curTick);
args.append(func);
args.append(file);
args.append(line);
-#else
- fmt += "\n";
#endif
+
args.dump(cerr, fmt);
+ if (outputStream != &cerr && outputStream != &cout)
+ args.dump(*outputStream, fmt);
delete &args;
}
diff --git a/base/statistics.cc b/base/statistics.cc
index 5c9a2bc65..49294ad27 100644
--- a/base/statistics.cc
+++ b/base/statistics.cc
@@ -116,7 +116,7 @@ Data::~Data()
{
if (stream) {
delete py;
- ccprintf(*stream, "if __name__ == '__main__':\n");
+ ccprintf(*stream, "\n\nif __name__ == '__main__':\n");
ccprintf(*stream, " program_display()\n");
stream->close();
delete stream;
@@ -209,30 +209,41 @@ Data::python_dump(const string &name, const string &subname)
++i;
}
}
- py->next();
}
void
Data::python(const string &name, const string &subname, const string &bin)
{
- py->start("collections.append");
- py->start("Collection");
+ py->name("collections.append");
+ py->newline();
+ py->name("Collection");
+ py->newline();
py->qarg(name);
+ py->newline();
py->qarg(subname);
+ py->newline();
py->qarg(bin);
+ py->newline();
py->qarg(hostname());
+ py->newline();
py->qarg(Time::start.date());
- py->startList();
+ py->newline();
+ py->list();
list_t::iterator i = allStats.begin();
list_t::iterator end = allStats.end();
while (i != end) {
StatData *stat = *i;
+ py->newline();
stat->python(*py);
++i;
}
- py->endList();
- py->end();
- py->end();
+ py->newline();
+ py->listEnd();
+ py->newline();
+ py->nameEnd();
+ py->newline();
+ py->nameEnd();
+ py->newline();
}
StatData *
@@ -996,7 +1007,7 @@ VectorDistDataBase::display(ostream &stream, DisplayMode mode) const
void
ScalarDataBase::python(Python &py) const
{
- py.start("Scalar");
+ py.name("Scalar");
py.qarg(name);
py.qqqarg(desc);
py.kwarg("binned", binned());
@@ -1005,7 +1016,7 @@ ScalarDataBase::python(Python &py) const
if (prereq)
py.qkwarg("prereq", prereq->name);
py.kwarg("value", val());
- py.end();
+ py.nameEnd();
}
void
@@ -1013,7 +1024,7 @@ VectorDataBase::python(Python &py) const
{
const_cast<VectorDataBase *>(this)->update();
- py.start("Vector");
+ py.name("Vector");
py.qarg(name);
py.qqqarg(desc);
py.kwarg("binned", binned());
@@ -1026,7 +1037,7 @@ VectorDataBase::python(Python &py) const
py.qkwarg("subnames", subnames);
if (!subdescs.empty())
py.qkwarg("subdescs", subdescs);
- py.end();
+ py.nameEnd();
}
void
@@ -1039,7 +1050,7 @@ DistDataData::python(Python &py, const string &name) const
else
s += "FullDist";
- py.start(s);
+ py.name(s);
py.arg(sum);
py.arg(squares);
py.arg(samples);
@@ -1054,7 +1065,7 @@ DistDataData::python(Python &py, const string &name) const
py.arg(bucket_size);
py.arg(size);
}
- py.end();
+ py.nameEnd();
}
void
@@ -1062,7 +1073,7 @@ FormulaDataBase::python(Python &py) const
{
const_cast<FormulaDataBase *>(this)->update();
- py.start("Formula");
+ py.name("Formula");
py.qarg(name);
py.qqqarg(desc);
py.kwarg("binned", binned());
@@ -1075,7 +1086,7 @@ FormulaDataBase::python(Python &py) const
py.qkwarg("subnames", subnames);
if (!subdescs.empty())
py.qkwarg("subdescs", subdescs);
- py.end();
+ py.nameEnd();
}
void
@@ -1083,7 +1094,7 @@ DistDataBase::python(Python &py) const
{
const_cast<DistDataBase *>(this)->update();
- py.start("Dist");
+ py.name("Dist");
py.qarg(name);
py.qqqarg(desc);
py.kwarg("binned", binned());
@@ -1092,7 +1103,7 @@ DistDataBase::python(Python &py) const
if (prereq)
py.qkwarg("prereq", prereq->name);
data.python(py, "dist");
- py.end();
+ py.nameEnd();
}
void
@@ -1100,7 +1111,7 @@ VectorDistDataBase::python(Python &py) const
{
const_cast<VectorDistDataBase *>(this)->update();
- py.start("VectorDist");
+ py.name("VectorDist");
py.qarg(name);
py.qqqarg(desc);
py.kwarg("binned", binned());
@@ -1121,8 +1132,8 @@ VectorDistDataBase::python(Python &py) const
i->python(py, "");
++i;
}
- py.endTuple();
- py.end();
+ py.tupleEnd();
+ py.nameEnd();
}
void
@@ -1130,7 +1141,7 @@ Vector2dDataBase::python(Python &py) const
{
const_cast<Vector2dDataBase *>(this)->update();
- py.start("Vector2d");
+ py.name("Vector2d");
py.qarg(name);
py.qqqarg(desc);
py.kwarg("binned", binned());
@@ -1149,7 +1160,7 @@ Vector2dDataBase::python(Python &py) const
py.kwarg("x", x);
py.kwarg("y", y);
- py.end();
+ py.nameEnd();
}
void
diff --git a/base/trace.cc b/base/trace.cc
index 99e97e7ea..156110376 100644
--- a/base/trace.cc
+++ b/base/trace.cc
@@ -49,7 +49,7 @@ FlagVec flags(NumFlags, false);
// directly; use DebugOut() (see below) to access this stream for
// output.
//
-ostream *dprintf_stream = NULL;
+ostream *dprintf_stream = &cerr;
int dprintf_ignore_size;
vector<string> dprintf_ignore;
@@ -267,10 +267,7 @@ RawDataRecord::dump(ostream &os)
std::ostream &
DebugOut()
{
- if (Trace::dprintf_stream)
- return *Trace::dprintf_stream;
- else
- return cerr;
+ return *Trace::dprintf_stream;
}
/////////////////////////////////////////////
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index adbd17a35..0d5fc4077 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -349,7 +349,7 @@ SimpleCPU::read(Addr addr, T& data, unsigned flags)
// Ugly hack to get an event scheduled *only* if the access is
// a miss. We really should add first-class support for this
// at some point.
- if (result != MA_HIT && dcacheInterface->doEvents) {
+ if (result != MA_HIT && dcacheInterface->doEvents()) {
memReq->completionEvent = &cacheCompletionEvent;
lastDcacheStall = curTick;
unscheduleTickEvent();
@@ -432,7 +432,7 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// Ugly hack to get an event scheduled *only* if the access is
// a miss. We really should add first-class support for this
// at some point.
- if (result != MA_HIT && dcacheInterface->doEvents) {
+ if (result != MA_HIT && dcacheInterface->doEvents()) {
memReq->completionEvent = &cacheCompletionEvent;
lastDcacheStall = curTick;
unscheduleTickEvent();
@@ -635,7 +635,7 @@ SimpleCPU::tick()
// Ugly hack to get an event scheduled *only* if the access is
// a miss. We really should add first-class support for this
// at some point.
- if (result != MA_HIT && icacheInterface->doEvents) {
+ if (result != MA_HIT && icacheInterface->doEvents()) {
memReq->completionEvent = &cacheCompletionEvent;
lastIcacheStall = curTick;
unscheduleTickEvent();
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc
index 359995693..89e121ed3 100644
--- a/dev/alpha_console.cc
+++ b/dev/alpha_console.cc
@@ -82,7 +82,7 @@ AlphaConsole::read(MemReqPtr req, uint8_t *data)
Addr daddr = req->paddr & addr_mask;
switch (daddr) {
case offsetof(AlphaAccess, inputChar):
- val = console->in();
+ val = console->console_in();
break;
default:
diff --git a/dev/console.cc b/dev/console.cc
index 08b169bc4..fb74c388a 100644
--- a/dev/console.cc
+++ b/dev/console.cc
@@ -228,27 +228,44 @@ SimConsole::configTerm()
#define RECEIVE_NONE (ULL(2) << 62)
#define RECEIVE_ERROR (ULL(3) << 62)
-uint64_t
-SimConsole::in()
+bool
+SimConsole::in(uint8_t &c)
{
- char c = 0;
- uint64_t val = 0;
- if (rxbuf.empty()) {
+ bool empty, ret;
+
+ empty = rxbuf.empty();
+ ret = !empty;
+ if (!empty) {
+ rxbuf.read((char *)&c, 1);
+ empty = rxbuf.empty();
+ }
+
+ if (empty)
clearInt(ReceiveInterrupt);
- val |= RECEIVE_NONE;
- return 0x8;
- } else {
- uint64_t val;
- rxbuf.read(&c, 1);
- val |= RECEIVE_SUCCESS | c;
+
+ DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x more: %d, return: %d\n",
+ isprint(c) ? c : ' ', c, !empty, ret);
+
+ return ret;
+}
+
+uint64_t
+SimConsole::console_in()
+{
+ uint8_t c;
+ uint64_t value;
+
+ if (in(c)) {
+ value = RECEIVE_SUCCESS | c;
if (!rxbuf.empty())
- val |= MORE_PENDING;
+ value |= MORE_PENDING;
+ } else {
+ value = RECEIVE_NONE;
}
- DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x retval: %#x\n",
- isprint(c) ? c : ' ', c, val);
+ DPRINTF(ConsoleVerbose, "console_in: return: %#x\n", value);
- return val;
+ return value;
}
void
@@ -383,8 +400,16 @@ END_INIT_SIM_OBJECT_PARAMS(SimConsole)
CREATE_SIM_OBJECT(SimConsole)
{
string filename = output;
- if (!filename.empty() && append_name)
- filename += "." + getInstanceName();
+ if (filename.empty()) {
+ if (!outputDirectory.empty())
+ filename = outputDirectory + getInstanceName();
+ } else {
+ if (append_name)
+ filename += "." + getInstanceName();
+ if (!outputDirectory.empty())
+ filename = outputDirectory + filename;
+ }
+
SimConsole *console = new SimConsole(getInstanceName(), filename, number);
((ConsoleListener *)listener)->add(console);
((SimConsole *)console)->initInt(intr_control);
diff --git a/dev/console.hh b/dev/console.hh
index 9913fe379..d2bba4612 100644
--- a/dev/console.hh
+++ b/dev/console.hh
@@ -109,7 +109,10 @@ class SimConsole : public SimObject
// OS interface
// Get a character from the console.
- // the return value corresponds to the console GETC return value:
+ bool in(uint8_t &value);
+
+ // get a character from the console in the console specific format
+ // corresponds to GETC:
// retval<63:61>
// 000: success: character received
// 001: success: character received, more pending
@@ -118,8 +121,9 @@ class SimConsole : public SimObject
// 111: failure: character received with error, more pending
// retval<31:0>
// character read from console
+ //
// Interrupts are cleared when the buffer is empty.
- uint64_t in();
+ uint64_t console_in();
// Send a character to the console
void out(char c, bool raise_int = true);
diff --git a/dev/etherdump.cc b/dev/etherdump.cc
index 60dc1559d..89f1ce382 100644
--- a/dev/etherdump.cc
+++ b/dev/etherdump.cc
@@ -126,13 +126,27 @@ END_DECLARE_SIM_OBJECT_PARAMS(EtherDump)
BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDump)
- INIT_PARAM_DFLT(file, "file to dump packets to", "")
+ INIT_PARAM(file, "file to dump packets to")
END_INIT_SIM_OBJECT_PARAMS(EtherDump)
CREATE_SIM_OBJECT(EtherDump)
{
- return new EtherDump(getInstanceName(), file);
+ 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);
}
REGISTER_SIM_OBJECT("EtherDump", EtherDump)
diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc
index 99d99afd4..07c655385 100644
--- a/kern/tru64/tru64_system.cc
+++ b/kern/tru64/tru64_system.cc
@@ -192,8 +192,10 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
//INSTRUMENTATION CODEGEN END
#endif //FS_MEASURE
+#ifdef DEBUG
kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
+#endif
badaddrEvent = new BadAddrEvent(&pcEventQueue, "badaddr");
skipPowerStateEvent = new SkipFuncEvent(&pcEventQueue,
"tl_v48_capture_power_state");
@@ -262,6 +264,7 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
strcpy(osflags, boot_osflags.c_str());
}
+#ifdef DEBUG
if (kernelSymtab->findAddress("panic", addr))
kernelPanicEvent->schedule(addr);
else
@@ -269,6 +272,7 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
if (consoleSymtab->findAddress("panic", addr))
consolePanicEvent->schedule(addr);
+#endif
if (kernelSymtab->findAddress("badaddr", addr))
badaddrEvent->schedule(addr);
@@ -511,8 +515,10 @@ Tru64System::~Tru64System()
delete kernelSymtab;
delete consoleSymtab;
+#ifdef DEBUG
delete kernelPanicEvent;
delete consolePanicEvent;
+#endif
delete badaddrEvent;
delete skipPowerStateEvent;
delete skipScavengeBootEvent;
diff --git a/sim/builder.cc b/sim/builder.cc
index fa435d322..e2345556e 100644
--- a/sim/builder.cc
+++ b/sim/builder.cc
@@ -34,10 +34,45 @@
#include "sim/configfile.hh"
#include "sim/host.hh"
#include "sim/sim_object.hh"
-#include "sim/sim_stats.hh"
+#include "sim/universe.hh"
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),
+ instanceName(_instanceName),
+ configNode(_configNode),
+ simObjClassName(_simObjClassName)
+{
+}
+
+SimObjectBuilder::~SimObjectBuilder()
+{
+}
+
///////////////////////////////////////////
//
// SimObjectBuilder member definitions
@@ -151,10 +186,10 @@ SimObjectClass::createObject(IniFile &configDB,
// echo object parameters to stats file (for documenting the
// config used to generate the associated stats)
- *statStream << "[" << object->name() << "]" << endl;
- *statStream << "type=" << simObjClassName << endl;
- objectBuilder->showParams(*statStream);
- *statStream << endl;
+ builderStream() << "[" << object->name() << "]" << endl;
+ builderStream() << "type=" << simObjClassName << endl;
+ objectBuilder->showParams(builderStream());
+ builderStream() << endl;
// done with the SimObjectBuilder now
delete objectBuilder;
diff --git a/sim/builder.hh b/sim/builder.hh
index 0364276bf..e13a85272 100644
--- a/sim/builder.hh
+++ b/sim/builder.hh
@@ -29,15 +29,18 @@
#ifndef __BUILDER_HH__
#define __BUILDER_HH__
-#include <map>
+#include <iosfwd>
#include <list>
+#include <map>
#include <vector>
-#include <iostream>
#include "sim/param.hh"
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
@@ -69,15 +72,9 @@ class SimObjectBuilder : public ParamContext
SimObjectBuilder(const std::string &_configClass,
const std::string &_instanceName,
ConfigNode *_configNode,
- const std::string &_simObjClassName)
- : ParamContext(_configClass, true),
- instanceName(_instanceName),
- configNode(_configNode),
- simObjClassName(_simObjClassName)
- {
- }
-
- virtual ~SimObjectBuilder() {}
+ const std::string &_simObjClassName);
+
+ virtual ~SimObjectBuilder();
// call parse() on all params in this context to convert string
// representations to parameter values
diff --git a/sim/main.cc b/sim/main.cc
index d0cf23039..48d64d4cd 100644
--- a/sim/main.cc
+++ b/sim/main.cc
@@ -54,6 +54,7 @@
#include "sim/sim_init.hh"
#include "sim/sim_object.hh"
#include "sim/sim_stats.hh"
+#include "sim/universe.hh"
using namespace std;
@@ -355,12 +356,12 @@ main(int argc, char **argv)
// Print hello message to stats file if it's actually a file. If
// it's not (i.e. it's cout or cerr) then we already did it above.
- if (statStreamIsFile)
- sayHello(*statStream);
+ if (outputStream != &cout && outputStream != &cerr)
+ sayHello(*outputStream);
// Echo command line and all parameter settings to stats file as well.
- echoCommandLine(argc, argv, *statStream);
- ParamContext::showAllContexts(*statStream);
+ echoCommandLine(argc, argv, *outputStream);
+ ParamContext::showAllContexts(builderStream());
// Now process the configuration hierarchy and create the SimObjects.
ConfigHierarchy configHierarchy(simConfigDB);
@@ -400,6 +401,7 @@ main(int argc, char **argv)
}
SimInit();
+ warn("Entering event queue. Starting simulation...\n");
while (!mainEventQueue.empty()) {
assert(curTick <= mainEventQueue.nextTick() &&
diff --git a/sim/serialize.cc b/sim/serialize.cc
index 33956c6e7..281e7cfc8 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -305,10 +305,9 @@ class SerializeParamContext : public ParamContext
SerializeParamContext serialParams("serialize");
-Param<string> serialize_dir(&serialParams,
- "dir",
+Param<string> serialize_dir(&serialParams, "dir",
"dir to stick checkpoint in "
- "(sprintf format with cycle #)", "m5.%012d");
+ "(sprintf format with cycle #)");
Param<Counter> serialize_cycle(&serialParams,
"cycle",
@@ -333,11 +332,18 @@ SerializeParamContext::~SerializeParamContext()
void
SerializeParamContext::checkParams()
{
- checkpointDirBase = serialize_dir;
+ if (serialize_dir.isValid()) {
+ checkpointDirBase = serialize_dir;
+ } else {
+ if (outputDirectory.empty())
+ checkpointDirBase = "m5.%012d";
+ else
+ checkpointDirBase = outputDirectory + "cpt.%012d";
+ }
+
// guarantee that directory ends with a '/'
- if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') {
+ if (checkpointDirBase[checkpointDirBase.size() - 1] != '/')
checkpointDirBase += "/";
- }
if (serialize_cycle > 0)
Checkpoint::setup(serialize_cycle, serialize_period);
diff --git a/sim/universe.cc b/sim/universe.cc
index b75b1f78a..feede514e 100644
--- a/sim/universe.cc
+++ b/sim/universe.cc
@@ -26,10 +26,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <cstring>
+#include <fstream>
#include <list>
#include <string>
#include <vector>
+#include "base/misc.hh"
#include "sim/universe.hh"
#include "sim/host.hh"
#include "sim/param.hh"
@@ -42,8 +48,14 @@ double __ticksPerMS;
double __ticksPerUS;
double __ticksPerNS;
+string outputDirectory;
+ostream *outputStream;
+
class UniverseParamContext : public ParamContext
{
+ private:
+ ofstream outputFile;
+
public:
UniverseParamContext(const string &is) : ParamContext(is) {}
void checkParams();
@@ -54,6 +66,11 @@ UniverseParamContext universe("Universe");
Param<Tick> universe_freq(&universe, "frequency", "tick frequency",
200000000);
+Param<string> universe_output_dir(&universe, "output_dir",
+ "directory to output data to");
+Param<string> universe_output_file(&universe, "output_file",
+ "file to dump simulator output to");
+
void
UniverseParamContext::checkParams()
{
@@ -62,4 +79,42 @@ UniverseParamContext::checkParams()
__ticksPerMS = freq / 1.0e3;
__ticksPerUS = freq / 1.0e6;
__ticksPerNS = freq / 1.0e9;
+
+ if (universe_output_dir.isValid()) {
+ outputDirectory = universe_output_dir;
+
+ // guarantee that directory ends with a '/'
+ if (outputDirectory[outputDirectory.size() - 1] != '/')
+ outputDirectory += "/";
+
+ if (mkdir(outputDirectory.c_str(), 0777) < 0) {
+ if (errno != EEXIST) {
+ panic("%s\ncould not make output directory: %s\n",
+ strerror(errno), outputDirectory);
+ }
+ }
+ }
+
+ 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;
+ }
}
diff --git a/test/stattest.cc b/test/stattest.cc
index d4ae5d1fd..8dd8eeb8e 100644
--- a/test/stattest.cc
+++ b/test/stattest.cc
@@ -510,10 +510,8 @@ main(int argc, char *argv[])
s12.sample(100);
// dump(cout, mode_simplescalar);
- ofstream file("/tmp/stats.py");
- dump(file, "stattest", mode_python);
- file.close();
-
+ python_start("/tmp/stats.py");
+ python_dump("stattest", "all");
return 0;
}