summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/pseudo_inst.cc2
-rw-r--r--base/cprintf.cc39
-rw-r--r--base/cprintf.hh2
-rw-r--r--base/cprintf_formats.hh19
-rw-r--r--base/statistics.cc123
-rw-r--r--base/statistics.hh10
-rw-r--r--dev/disk_image.cc2
-rw-r--r--sim/serialize.cc39
-rw-r--r--sim/serialize.hh24
9 files changed, 158 insertions, 102 deletions
diff --git a/arch/alpha/pseudo_inst.cc b/arch/alpha/pseudo_inst.cc
index c5d82bd21..7f8c6b17c 100644
--- a/arch/alpha/pseudo_inst.cc
+++ b/arch/alpha/pseudo_inst.cc
@@ -127,7 +127,7 @@ namespace AlphaPseudo
Tick when = curTick + NS2Ticks(delay);
Tick repeat = NS2Ticks(period);
- SetupCheckpoint(when, repeat);
+ Checkpoint::setup(when, repeat);
}
class Context : public ParamContext
diff --git a/base/cprintf.cc b/base/cprintf.cc
index af3b26a57..5796a712b 100644
--- a/base/cprintf.cc
+++ b/base/cprintf.cc
@@ -45,8 +45,6 @@ ArgList::dump(const string &format)
stream->fill(' ');
stream->flags((ios::fmtflags)0);
- Format fmt;
-
while (*p) {
switch (*p) {
case '%': {
@@ -56,12 +54,7 @@ ArgList::dump(const string &format)
continue;
}
- if (objects.empty())
- format_invalid(*stream);
-
- Base *data = objects.front();
-
- fmt.clear();
+ Format fmt;
bool done = false;
bool end_number = false;
bool have_precision = false;
@@ -205,18 +198,26 @@ ArgList::dump(const string &format)
}
}
- ios::fmtflags saved_flags = stream->flags();
- char old_fill = stream->fill();
- int old_precision = stream->precision();
+ if (!objects.empty())
+ {
+ 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);
+ data->process(*stream, fmt);
- stream->flags(saved_flags);
- stream->fill(old_fill);
- stream->precision(old_precision);
+ stream->flags(saved_flags);
+ stream->fill(old_fill);
+ stream->precision(old_precision);
+
+ delete data;
+ } else {
+ *stream << "<missing arg for format>";
+ }
- delete data;
- objects.pop_front();
++p;
}
break;
@@ -241,10 +242,10 @@ ArgList::dump(const string &format)
}
while (!objects.empty()) {
+ *stream << "<extra arg>";
Base *data = objects.front();
- data->process(*stream, fmt);
- delete data;
objects.pop_front();
+ delete data;
}
}
diff --git a/base/cprintf.hh b/base/cprintf.hh
index 8360d227c..ac34cd252 100644
--- a/base/cprintf.hh
+++ b/base/cprintf.hh
@@ -75,7 +75,7 @@ class ArgList
break;
default:
- format_invalid(out);
+ out << "<bad format>";
break;
}
}
diff --git a/base/cprintf_formats.hh b/base/cprintf_formats.hh
index 1e5de4fdf..b921c0506 100644
--- a/base/cprintf_formats.hh
+++ b/base/cprintf_formats.hh
@@ -43,8 +43,10 @@ struct Format
int precision;
int width;
- Format() { }
- void clear() {
+ Format() { clear(); }
+
+ void clear()
+ {
alternate_form = false;
flush_left = false;
print_sign = false;
@@ -58,15 +60,6 @@ struct Format
}
};
-inline void
-format_invalid(std::ostream &out)
-{
- using namespace std;
-
- out << "format invalid!!!" << endl;
-}
-
-
template <typename T>
inline void
_format_char(std::ostream &out, const T& data, Format &fmt)
@@ -233,7 +226,7 @@ _format_string(std::ostream &out, const T& data, Format &fmt)
template <typename T>
inline void
format_char(std::ostream &out, const T& data, Format &fmt)
-{ format_invalid(out); }
+{ out << "<bad arg type for char format>"; }
inline void
format_char(std::ostream &out, char data, Format &fmt)
@@ -329,7 +322,7 @@ format_integer(std::ostream &out, unsigned long long data, Format &fmt)
template <typename T>
inline void
format_float(std::ostream &out, const T& data, Format &fmt)
-{ format_invalid(out); }
+{ out << "<bad arg type for float format>"; }
inline void
format_float(std::ostream &out, float data, Format &fmt)
diff --git a/base/statistics.cc b/base/statistics.cc
index 04d4032d3..5c9a2bc65 100644
--- a/base/statistics.cc
+++ b/base/statistics.cc
@@ -27,7 +27,7 @@
*/
#include <iomanip>
-#include <iostream>
+#include <fstream>
#include <list>
#include <map>
#include <string>
@@ -82,11 +82,19 @@ namespace Database
list_t printStats;
map_t statMap;
+ ofstream *stream;
+ Python *py;
+
public:
- void dump(ostream &stream, const string &name, DisplayMode mode);
+ Data();
+ ~Data();
+
+ void dump(ostream &stream, DisplayMode mode);
void display(ostream &stream, DisplayMode mode);
- void python(ostream &stream, const string &name);
- void python(Python &py, const string &name, const string &bin);
+ void python_start(const string &file);
+ void python_dump(const string &name, const string &subname);
+ void python(const string &name, const string &subname,
+ const string &bin);
StatData *find(void *stat);
void mapStat(void *stat, StatData *data);
@@ -99,16 +107,28 @@ namespace Database
static std::string name() { return "Statistics Database"; }
};
+Data::Data()
+ : stream(0), py(0)
+{
+}
+
+Data::~Data()
+{
+ if (stream) {
+ delete py;
+ ccprintf(*stream, "if __name__ == '__main__':\n");
+ ccprintf(*stream, " program_display()\n");
+ stream->close();
+ delete stream;
+ }
+}
void
-Data::dump(ostream &stream, const string &name, DisplayMode mode)
+Data::dump(ostream &stream, DisplayMode mode)
{
MainBin *orig = MainBin::curBin();
switch (mode) {
- case mode_python:
- python(stream, name);
- break;
case mode_m5:
case mode_simplescalar:
display(stream, mode);
@@ -158,50 +178,61 @@ Data::display(ostream &stream, DisplayMode mode)
}
void
-Data::python(ostream &stream, const string &name)
+Data::python_start(const string &file)
{
- Python py(stream);
+ if (stream)
+ panic("can't start python twice!");
- ccprintf(stream, "import sys\n");
- ccprintf(stream, "sys.path.append('.')\n");
- ccprintf(stream, "from m5stats import *\n\n");
+ stream = new ofstream(file.c_str(), ios::trunc);
+ py = new Python(*stream);
+
+ ccprintf(*stream, "import sys\n");
+ ccprintf(*stream, "sys.path.append('.')\n");
+ ccprintf(*stream, "from m5stats import *\n\n");
+}
+
+void
+Data::python_dump(const string &name, const string &subname)
+{
+ if (!py)
+ panic("Can't dump python without first opening the file");
if (bins.empty()) {
- python(py, name, "");
+ python(name, subname, "");
} else {
list<MainBin *>::iterator i = bins.begin();
list<MainBin *>::iterator end = bins.end();
while (i != end) {
(*i)->activate();
- python(py, name, (*i)->name());
+ python(name, subname, (*i)->name());
++i;
}
}
-
- py.next();
- ccprintf(stream, "if __name__ == '__main__':\n");
- ccprintf(stream, " program_display()\n");
+ py->next();
}
void
-Data::python(Python &py, const string &name, const string &bin)
+Data::python(const string &name, const string &subname, const string &bin)
{
- py.start("collections.append");
- py.start("Collection");
- py.qarg(name);
- py.qarg(bin);
- py.qarg(hostname());
- py.qarg(Time::start.date());
+ py->start("collections.append");
+ py->start("Collection");
+ py->qarg(name);
+ py->qarg(subname);
+ py->qarg(bin);
+ py->qarg(hostname());
+ py->qarg(Time::start.date());
+ py->startList();
list_t::iterator i = allStats.begin();
list_t::iterator end = allStats.end();
while (i != end) {
StatData *stat = *i;
- stat->python(py);
+ stat->python(*py);
++i;
}
- py.end();
- py.end();
+ py->endList();
+ py->end();
+ py->end();
}
StatData *
@@ -967,7 +998,7 @@ ScalarDataBase::python(Python &py) const
{
py.start("Scalar");
py.qarg(name);
- py.qarg(desc);
+ py.qqqarg(desc);
py.kwarg("binned", binned());
py.kwarg("precision", precision);
py.kwarg("flags", flags);
@@ -984,7 +1015,7 @@ VectorDataBase::python(Python &py) const
py.start("Vector");
py.qarg(name);
- py.qarg(desc);
+ py.qqqarg(desc);
py.kwarg("binned", binned());
py.kwarg("precision", precision);
py.kwarg("flags", flags);
@@ -1033,7 +1064,7 @@ FormulaDataBase::python(Python &py) const
py.start("Formula");
py.qarg(name);
- py.qarg(desc);
+ py.qqqarg(desc);
py.kwarg("binned", binned());
py.kwarg("precision", precision);
py.kwarg("flags", flags);
@@ -1054,7 +1085,7 @@ DistDataBase::python(Python &py) const
py.start("Dist");
py.qarg(name);
- py.qarg(desc);
+ py.qqqarg(desc);
py.kwarg("binned", binned());
py.kwarg("precision", precision);
py.kwarg("flags", flags);
@@ -1071,7 +1102,7 @@ VectorDistDataBase::python(Python &py) const
py.start("VectorDist");
py.qarg(name);
- py.qarg(desc);
+ py.qqqarg(desc);
py.kwarg("binned", binned());
py.kwarg("precision", precision);
py.kwarg("flags", flags);
@@ -1101,7 +1132,7 @@ Vector2dDataBase::python(Python &py) const
py.start("Vector2d");
py.qarg(name);
- py.qarg(desc);
+ py.qqqarg(desc);
py.kwarg("binned", binned());
py.kwarg("precision", precision);
py.kwarg("flags", flags);
@@ -1124,13 +1155,14 @@ Vector2dDataBase::python(Python &py) const
void
FormulaBase::val(rvec_t &vec) const
{
- vec = root->val();
+ if (root)
+ vec = root->val();
}
result_t
FormulaBase::total() const
{
- return root->total();
+ return root ? root->total() : 0.0;
}
size_t
@@ -1240,11 +1272,24 @@ check()
}
void
-dump(ostream &stream, const string &name, DisplayMode mode)
+dump(ostream &stream, DisplayMode mode)
+{
+ Database::StatDB().dump(stream, mode);
+}
+
+void
+python_start(const string &file)
{
- Database::StatDB().dump(stream, name, mode);
+ Database::StatDB().python_start(file);
}
+void
+python_dump(const string &name, const string &subname)
+{
+ Database::StatDB().python_dump(name, subname);
+}
+
+
CallbackQueue resetQueue;
void
diff --git a/base/statistics.hh b/base/statistics.hh
index 8c7566391..ce20043a3 100644
--- a/base/statistics.hh
+++ b/base/statistics.hh
@@ -120,8 +120,7 @@ const StatFlags __reserved = init | print | __substat;
enum DisplayMode
{
mode_m5,
- mode_simplescalar,
- mode_python
+ mode_simplescalar
};
extern DisplayMode DefaultMode;
@@ -2931,7 +2930,7 @@ class Temp;
class Formula
: public WrapVec<Formula,
FormulaBase,
- VectorData>
+ FormulaData>
{
public:
/**
@@ -3132,8 +3131,9 @@ class Temp
*/
void check();
-void dump(std::ostream &stream, const std::string &name = "",
- DisplayMode mode = DefaultMode);
+void dump(std::ostream &stream, DisplayMode mode = DefaultMode);
+void python_start(const std::string &file);
+void python_dump(const std::string &name, const std::string &subname);
void reset();
void registerResetCallback(Callback *cb);
diff --git a/dev/disk_image.cc b/dev/disk_image.cc
index 02c8b50b6..142fb60a5 100644
--- a/dev/disk_image.cc
+++ b/dev/disk_image.cc
@@ -405,7 +405,7 @@ CowDiskImage::write(const uint8_t *data, off_t offset)
void
CowDiskImage::serialize(ostream &os)
{
- string cowFilename = CheckpointDir() + name() + ".cow";
+ string cowFilename = Checkpoint::dir() + name() + ".cow";
SERIALIZE_SCALAR(cowFilename);
save(cowFilename);
}
diff --git a/sim/serialize.cc b/sim/serialize.cc
index 95aacc361..33956c6e7 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -222,11 +222,11 @@ Globals::unserialize(Checkpoint *cp)
void
Serializable::serializeAll()
{
- string dir = CheckpointDir();
+ string dir = Checkpoint::dir();
if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
- warn("could mkdir %s\n", dir);
+ fatal("couldn't mkdir %s\n", dir);
- string cpt_file = dir + "m5.cpt";
+ string cpt_file = dir + Checkpoint::baseFilename;
ofstream outstream(cpt_file.c_str());
time_t t = time(NULL);
outstream << "// checkpoint generated: " << ctime(&t);
@@ -273,19 +273,21 @@ SerializeEvent::process()
schedule(curTick + repeat);
}
-string __CheckpointDirBase;
+const char *Checkpoint::baseFilename = "m5.cpt";
+
+static string checkpointDirBase;
string
-CheckpointDir()
+Checkpoint::dir()
{
- if (__CheckpointDirBase.empty())
- return __CheckpointDirBase;
-
- return csprintf("%s/m5.%012d/", __CheckpointDirBase, curTick);
+ // use csprintf to insert curTick into directory name if it
+ // appears to have a format placeholder in it.
+ return (checkpointDirBase.find("%") != string::npos) ?
+ csprintf(checkpointDirBase, curTick) : checkpointDirBase;
}
void
-SetupCheckpoint(Tick when, Tick period)
+Checkpoint::setup(Tick when, Tick period)
{
new SerializeEvent(when, period);
}
@@ -304,8 +306,9 @@ class SerializeParamContext : public ParamContext
SerializeParamContext serialParams("serialize");
Param<string> serialize_dir(&serialParams,
- "dir",
- "dir to stick checkpoint in", ".");
+ "dir",
+ "dir to stick checkpoint in "
+ "(sprintf format with cycle #)", "m5.%012d");
Param<Counter> serialize_cycle(&serialParams,
"cycle",
@@ -330,9 +333,14 @@ SerializeParamContext::~SerializeParamContext()
void
SerializeParamContext::checkParams()
{
- __CheckpointDirBase = serialize_dir;
+ checkpointDirBase = serialize_dir;
+ // guarantee that directory ends with a '/'
+ if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') {
+ checkpointDirBase += "/";
+ }
+
if (serialize_cycle > 0)
- SetupCheckpoint(serialize_cycle, serialize_period);
+ Checkpoint::setup(serialize_cycle, serialize_period);
}
void
@@ -415,10 +423,11 @@ Serializable::create(Checkpoint *cp, const std::string &section)
}
-Checkpoint::Checkpoint(const std::string &filename, const std::string &path,
+Checkpoint::Checkpoint(const std::string &cpt_dir, const std::string &path,
const ConfigNode *_configNode)
: db(new IniFile), basePath(path), configNode(_configNode)
{
+ string filename = cpt_dir + "/" + Checkpoint::baseFilename;
if (!db->load(filename)) {
fatal("Can't load checkpoint file '%s'\n", filename);
}
diff --git a/sim/serialize.hh b/sim/serialize.hh
index 60e06f94b..32802409d 100644
--- a/sim/serialize.hh
+++ b/sim/serialize.hh
@@ -207,7 +207,7 @@ class Checkpoint
std::map<std::string, Serializable*> objMap;
public:
- Checkpoint(const std::string &filename, const std::string &path,
+ Checkpoint(const std::string &cpt_dir, const std::string &path,
const ConfigNode *_configNode);
bool find(const std::string &section, const std::string &entry,
@@ -217,14 +217,22 @@ class Checkpoint
Serializable *&value);
bool sectionExists(const std::string &section);
-};
+ // The following static functions have to do with checkpoint
+ // creation rather than restoration. This class makes a handy
+ // namespace for them though.
-//
-// Export checkpoint filename param so other objects can derive
-// filenames from it (e.g., memory).
-//
-std::string CheckpointDir();
-void SetupCheckpoint(Tick when, Tick period = 0);
+ // Export current checkpoint directory name so other objects can
+ // derive filenames from it (e.g., memory). The return value is
+ // guaranteed to end in '/' so filenames can be directly appended.
+ // This function is only valid while a checkpoint is being created.
+ static std::string dir();
+
+ // Filename for base checkpoint file within directory.
+ static const char *baseFilename;
+
+ // Set up a checkpoint creation event or series of events.
+ static void setup(Tick when, Tick period = 0);
+};
#endif // __SERIALIZE_HH__