diff options
-rw-r--r-- | arch/alpha/pseudo_inst.cc | 2 | ||||
-rw-r--r-- | base/cprintf.cc | 39 | ||||
-rw-r--r-- | base/cprintf.hh | 2 | ||||
-rw-r--r-- | base/cprintf_formats.hh | 19 | ||||
-rw-r--r-- | base/statistics.cc | 123 | ||||
-rw-r--r-- | base/statistics.hh | 10 | ||||
-rw-r--r-- | dev/disk_image.cc | 2 | ||||
-rw-r--r-- | sim/serialize.cc | 39 | ||||
-rw-r--r-- | sim/serialize.hh | 24 |
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 §ion) } -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 §ion, const std::string &entry, @@ -217,14 +217,22 @@ class Checkpoint Serializable *&value); bool sectionExists(const std::string §ion); -}; + // 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__ |