From e94103397c58ffe05d4c5c7f536edabfb1d6861b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 17 Feb 2007 22:52:32 -0800 Subject: [PATCH] Get rid of the Statistics and Statreset ParamContexts, and expose all of the relevant functionality to python. Clean up the mysql code while we're at it. --HG-- extra : convert_revision : 5b711202a5a452b8875ebefb136a156b65c24279 --- src/SConscript | 3 +- src/base/statistics.hh | 1 + src/base/stats/mysql.cc | 70 ++++++++++++++++++------- src/base/stats/mysql.hh | 31 ++++++++++- src/base/stats/output.cc | 70 +++++++++++++++++++++++++ src/base/stats/text.cc | 21 ++++++++ src/base/stats/text.hh | 3 ++ src/python/SConscript | 1 + src/python/m5/main.py | 2 +- src/python/m5/objects/Root.py | 4 -- src/python/swig/stats.i | 60 ++++++++++++++++++++++ src/sim/main.cc | 14 ++--- src/sim/pseudo_inst.cc | 10 ++-- src/sim/serialize.cc | 33 ------------ src/sim/stat_control.cc | 96 +++++++++-------------------------- src/sim/stat_control.hh | 19 +------ 16 files changed, 274 insertions(+), 164 deletions(-) create mode 100644 src/base/stats/output.cc create mode 100644 src/python/swig/stats.i diff --git a/src/SConscript b/src/SConscript index d6b4c6c8d..c93605ff7 100644 --- a/src/SConscript +++ b/src/SConscript @@ -79,6 +79,7 @@ base_sources = Split(''' base/loader/object_file.cc base/loader/symtab.cc base/stats/events.cc + base/stats/output.cc base/stats/statdb.cc base/stats/visit.cc base/stats/text.cc @@ -134,6 +135,7 @@ base_sources = Split(''' python/swig/main_wrap.cc python/swig/event_wrap.cc python/swig/random_wrap.cc + python/swig/stats_wrap.cc python/swig/trace_wrap.cc python/swig/pyevent.cc @@ -148,7 +150,6 @@ base_sources = Split(''' sim/sim_events.cc sim/sim_object.cc sim/startup.cc - sim/stat_context.cc sim/stat_control.cc sim/system.cc ''') diff --git a/src/base/statistics.hh b/src/base/statistics.hh index 2b1b327e5..8168473a1 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -2839,6 +2839,7 @@ class Temp */ void check(); +void dump(); void reset(); void registerResetCallback(Callback *cb); diff --git a/src/base/stats/mysql.cc b/src/base/stats/mysql.cc index 0fb31f4ce..01a82c4bf 100644 --- a/src/base/stats/mysql.cc +++ b/src/base/stats/mysql.cc @@ -49,14 +49,6 @@ using namespace std; namespace Stats { -MySqlRun MySqlDB; - -bool -MySqlConnected() -{ - return MySqlDB.connected(); -} - void MySqlRun::connect(const string &host, const string &user, const string &passwd, const string &db, const string &name, const string &sample, @@ -198,7 +190,7 @@ SetupStat::init() unsigned SetupStat::setup() { - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); stringstream insert; ccprintf(insert, @@ -317,7 +309,7 @@ void InsertData::flush() { if (size) { - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); mysql.query(query); if (mysql.error) @@ -349,7 +341,7 @@ InsertData::insert() first = false; size += sprintf(query + size, "(%u,%d,%d,%u,%llu,\"%f\")", - stat, x, y, MySqlDB.run(), (unsigned long long)tick, + stat, x, y, run->run(), (unsigned long long)tick, data); } @@ -367,7 +359,7 @@ struct InsertSubData void InsertSubData::setup() { - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); stringstream insert; ccprintf(insert, @@ -386,7 +378,7 @@ InsertSubData::setup() void InsertFormula(uint16_t stat, const string &formula) { - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); stringstream insert_formula; ccprintf(insert_formula, @@ -400,7 +392,7 @@ InsertFormula(uint16_t stat, const string &formula) stringstream insert_ref; ccprintf(insert_ref, "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)", - stat, MySqlDB.run()); + stat, run->run()); mysql.query(insert_ref); // if (mysql.error) @@ -413,7 +405,7 @@ InsertFormula(uint16_t stat, const string &formula) void UpdatePrereq(uint16_t stat, uint16_t prereq) { - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); stringstream update; ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d", @@ -426,6 +418,29 @@ UpdatePrereq(uint16_t stat, uint16_t prereq) panic("could not commit transaction\n%s\n", mysql.error); } +MySql::MySql() + : run(new MySqlRun) +{} + +MySql::~MySql() +{ + delete run; +} + +void +MySql::connect(const string &host, const string &user, const string &passwd, + const string &db, const string &name, const string &sample, + const string &project) +{ + run->connect(host, user, passwd, db, name, sample, project); +} + +bool +MySql::connected() const +{ + run->connected(); +} + void MySql::configure() { @@ -434,7 +449,7 @@ MySql::configure() */ using namespace Database; - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); stat_list_t::const_iterator i, end = stats().end(); for (i = stats().begin(); i != end; ++i) { @@ -605,7 +620,7 @@ MySql::configure(const FormulaData &data) bool MySql::valid() const { - return MySqlDB.connected(); + return run->connected(); } void @@ -620,7 +635,7 @@ MySql::output() // store sample # newdata.tick = curTick; - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); Database::stat_list_t::const_iterator i, end = Database::stats().end(); for (i = Database::stats().begin(); i != end; ++i) { @@ -825,4 +840,21 @@ MySql::visit(const FormulaData &data) output(data); } -/* namespace Stats */ } +bool +initMySQL(string host, string user, string password, string database, + string name, string sample, string project) +{ + extern list OutputList; + static MySql mysql; + + if (mysql.connected()) + return false; + + if (user.empty()) + user = username(); + + mysql.connect(host, user, password, database, name, sample, project); + OutputList.push_back(&mysql); + + return true; +} diff --git a/src/base/stats/mysql.hh b/src/base/stats/mysql.hh index 50f7d9e97..a43c74ecc 100644 --- a/src/base/stats/mysql.hh +++ b/src/base/stats/mysql.hh @@ -35,14 +35,13 @@ #include #include "base/stats/output.hh" +#include "config/use_mysql.hh" namespace MySQL { class Connection; } namespace Stats { class DistDataData; class MySqlRun; -bool MySqlConnected(); -extern MySqlRun MySqlDB; struct SetupStat { @@ -95,6 +94,9 @@ class InsertData class MySql : public Output { protected: + MySqlRun *run; /* Hide the implementation so we don't have a + #include mess */ + SetupStat stat; InsertData newdata; std::list formulas; @@ -116,6 +118,17 @@ class MySql : public Output assert(i != idmap.end()); return (*i).second; } + + public: + MySql(MySqlRun &_run){} + ~MySql(); + + void connect(const std::string &host, const std::string &user, + const std::string &passwd, const std::string &db, + const std::string &name, const std::string &sample, + const std::string &project); + bool connected() const; + public: // Implement Visit virtual void visit(const ScalarData &data); @@ -149,6 +162,20 @@ class MySql : public Output void configure(const FormulaData &data); }; +bool initMySQL(std::string host, std::string database, std::string user = "", + std::string passwd = "", std::string name = "test", + std::string sample = "0", std::string project = "test"); + +#if !USE_MYSQL +inline bool +initMySQL(std::string host, std::string user, std::string password, + std::string database, std::string name, std::string sample, + std::string project) +{ + return false; +} +#endif + /* namespace Stats */ } #endif // __BASE_STATS_MYSQL_HH__ diff --git a/src/base/stats/output.cc b/src/base/stats/output.cc new file mode 100644 index 000000000..9f2b91c77 --- /dev/null +++ b/src/base/stats/output.cc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include + +#include "base/stats/output.hh" +#include "sim/eventq.hh" +#include "sim/host.hh" + +using namespace std; + +namespace Stats { + +Tick lastDump(0); +list OutputList; + +void +dump() +{ + assert(lastDump <= curTick); + if (lastDump == curTick) + return; + lastDump = curTick; + + list::iterator i = OutputList.begin(); + list::iterator end = OutputList.end(); + for (; i != end; ++i) { + Output *output = *i; + if (!output->valid()) + continue; + + output->output(); + } +} + +/* namespace Stats */ } + +void +debugDumpStats() +{ + Stats::dump(); +} + diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc index ae0d65537..66c5955d7 100644 --- a/src/base/stats/text.cc +++ b/src/base/stats/text.cc @@ -725,4 +725,25 @@ Text::visit(const FormulaData &data) visit((const VectorData &)data); } +bool +initText(const string &filename, bool desc, bool compat) +{ + static Text text; + static bool connected = false; + + if (connected) + return false; + + extern list OutputList; + + text.open(*simout.find(filename)); + text.descriptions = desc; + text.compat = compat; + OutputList.push_back(&text); + connected = true; + + return true; +} + + /* namespace Stats */ } diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh index b3faf5ad5..0516bc60d 100644 --- a/src/base/stats/text.hh +++ b/src/base/stats/text.hh @@ -34,6 +34,7 @@ #include #include +#include "base/output.hh" #include "base/stats/output.hh" namespace Stats { @@ -73,6 +74,8 @@ class Text : public Output virtual void output(); }; +bool initText(const std::string &filename, bool desc=true, bool compat=true); + /* namespace Stats */ } #endif // __BASE_STATS_TEXT_HH__ diff --git a/src/python/SConscript b/src/python/SConscript index 51271650f..4dd614cfb 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -110,6 +110,7 @@ swig_it('main') swig_it('debug') swig_it('event') swig_it('random') +swig_it('stats') swig_it('trace') # Action function to build the zip archive. Uses the PyZipFile module diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 98dc829d4..48c75434f 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -264,7 +264,7 @@ def main(): import objects # set stats options - objects.Statistics.text_file = options.stats_file + internal.stats.initText(options.stats_file) # set debugging options for when in options.debug_break: diff --git a/src/python/m5/objects/Root.py b/src/python/m5/objects/Root.py index c78ae6ccb..cf5174ef3 100644 --- a/src/python/m5/objects/Root.py +++ b/src/python/m5/objects/Root.py @@ -1,8 +1,6 @@ from m5.SimObject import SimObject from m5.params import * from Serialize import Serialize -from Serialize import Statreset -from Statistics import Statistics class Root(SimObject): type = 'Root' @@ -12,7 +10,5 @@ class Root(SimObject): "print a progress message every n ticks (0 = never)") output_file = Param.String('cout', "file to dump simulator output to") checkpoint = Param.String('', "checkpoint file to load") -# stats = Param.Statistics(Statistics(), "statistics object") # serialize = Param.Serialize(Serialize(), "checkpoint generation options") - stats = Statistics() serialize = Serialize() diff --git a/src/python/swig/stats.i b/src/python/swig/stats.i new file mode 100644 index 000000000..d6b39c2cb --- /dev/null +++ b/src/python/swig/stats.i @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +%module stats + +%include "std_string.i" + +%{ +#include "base/statistics.hh" +#include "base/stats/mysql.hh" +#include "base/stats/text.hh" +#include "sim/stat_control.hh" +%} + +namespace Stats { +void initSimStats(); +void initText(const std::string &filename, bool desc=true, bool compat=true); +void initMySQL(std::string host, std::string database, std::string user = "", + std::string passwd = "", std::string name = "test", + std::string sample = "0", std::string project = "test"); + +void StatEvent(bool dump, bool reset, Tick when = curTick, Tick repeat = 0); + +void dump(); +void reset(); + +/* namespace Stat */ } + +%wrapper %{ +// fix up module name to reflect the fact that it's inside the m5 package +#undef SWIG_name +#define SWIG_name "m5.internal._stats" +%} diff --git a/src/sim/main.cc b/src/sim/main.cc index 13850f255..45819f880 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -53,6 +53,7 @@ #include "base/output.hh" #include "base/pollevent.hh" #include "base/statistics.hh" +#include "base/stats/output.hh" #include "base/str.hh" #include "base/time.hh" #include "config/pythonhome.hh" @@ -220,7 +221,7 @@ loadIniFile(PyObject *_resolveFunc) inifile.load(simout.resolve("config.ini")); // Initialize statistics database - Stats::InitSimStats(); + Stats::initSimStats(); } @@ -297,7 +298,6 @@ finalInit() SimStartup(); } - /** Simulate for num_cycles additional cycles. If num_cycles is -1 * (the default), do not limit simulation; some other event must * terminate the loop. Exported to Python via SWIG. @@ -350,16 +350,12 @@ simulate(Tick num_cycles = MaxTick) async_event = false; if (async_dump) { async_dump = false; - - using namespace Stats; - SetupEvent(Dump, curTick); + Stats::StatEvent(true, false); } if (async_dumpreset) { async_dumpreset = false; - - using namespace Stats; - SetupEvent(Dump | Reset, curTick); + Stats::StatEvent(true, true); } if (async_exit) { @@ -469,5 +465,5 @@ doExitCleanup() ParamContext::cleanupAllContexts(); // print simulation stats - Stats::DumpNow(); + Stats::dump(); } diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 4a8c0eb66..66ebc10e1 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -32,6 +32,7 @@ #include #include +#include #include #include "arch/vtophys.hh" @@ -199,8 +200,7 @@ namespace AlphaPseudo Tick when = curTick + delay * Clock::Int::ns; Tick repeat = period * Clock::Int::ns; - using namespace Stats; - SetupEvent(Reset, when, repeat); + Stats::StatEvent(false, true, when, repeat); } void @@ -213,8 +213,7 @@ namespace AlphaPseudo Tick when = curTick + delay * Clock::Int::ns; Tick repeat = period * Clock::Int::ns; - using namespace Stats; - SetupEvent(Dump, when, repeat); + Stats::StatEvent(true, false, when, repeat); } void @@ -254,8 +253,7 @@ namespace AlphaPseudo Tick when = curTick + delay * Clock::Int::ns; Tick repeat = period * Clock::Int::ns; - using namespace Stats; - SetupEvent(Dump|Reset, when, repeat); + Stats::StatEvent(true, true, when, repeat); } void diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 1ff16976d..d32bb1142 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -407,36 +407,3 @@ Checkpoint::sectionExists(const std::string §ion) { return db->sectionExists(section); } - -/** Hacked stat reset event */ - -class StatresetParamContext : public ParamContext -{ - public: - StatresetParamContext(const string §ion); - ~StatresetParamContext(); - void startup(); -}; - -StatresetParamContext statParams("statsreset"); - -Param reset_cycle(&statParams, "reset_cycle", - "Cycle to reset stats on", 0); - -StatresetParamContext::StatresetParamContext(const string §ion) - : ParamContext(section) -{ } - -StatresetParamContext::~StatresetParamContext() -{ -} - -void -StatresetParamContext::startup() -{ - if (reset_cycle > 0) { - Stats::SetupEvent(Stats::Reset, curTick + reset_cycle, 0); - cprintf("Stats reset event scheduled for %lli\n", - curTick + reset_cycle); - } -} diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc index 3fad8beb5..228c83898 100644 --- a/src/sim/stat_control.cc +++ b/src/sim/stat_control.cc @@ -38,14 +38,9 @@ #include "base/callback.hh" #include "base/hostinfo.hh" #include "base/statistics.hh" -#include "base/str.hh" #include "base/time.hh" -#include "base/stats/output.hh" #include "cpu/base.hh" #include "sim/eventq.hh" -#include "sim/sim_object.hh" -#include "sim/stat_control.hh" -#include "sim/root.hh" using namespace std; @@ -63,11 +58,9 @@ namespace Stats { Time statTime(true); Tick startTick; -Tick lastDump(0); -class SimTicksReset : public Callback +struct SimTicksReset : public Callback { - public: void process() { statTime.set(); @@ -92,7 +85,7 @@ statElapsedTicks() SimTicksReset simTicksReset; void -InitSimStats() +initSimStats() { simInsts .functor(BaseCPU::numSimulatedInstructions) @@ -153,81 +146,40 @@ InitSimStats() registerResetCallback(&simTicksReset); } -class StatEvent : public Event +class _StatEvent : public Event { - protected: - int flags; + private: + bool dump; + bool reset; Tick repeat; public: - StatEvent(EventQueue *queue, int _flags, Tick _when, Tick _repeat); - virtual void process(); - virtual const char *description(); -}; - -StatEvent::StatEvent(EventQueue *queue, int _flags, Tick _when, Tick _repeat) - : Event(queue, Stat_Event_Pri), - flags(_flags), repeat(_repeat) -{ - setFlags(AutoDelete); - schedule(_when); -} - -const char * -StatEvent::description() -{ - return "Statistics dump and/or reset"; -} - -void -StatEvent::process() -{ - if (flags & Stats::Dump) - DumpNow(); - - if (flags & Stats::Reset) { - cprintf("Resetting stats at cycle %d!\n", curTick); - reset(); + _StatEvent(bool _dump, bool _reset, Tick _when, Tick _repeat) + : Event(&mainEventQueue, Stat_Event_Pri), dump(_dump), reset(_reset), + repeat(_repeat) + { + setFlags(AutoDelete); + schedule(_when); } - if (repeat) - schedule(curTick + repeat); -} + virtual void + process() + { + if (dump) + Stats::dump(); -list OutputList; + if (reset) + Stats::reset(); -void -DumpNow() -{ - assert(lastDump <= curTick); - if (lastDump == curTick) - return; - lastDump = curTick; - - list::iterator i = OutputList.begin(); - list::iterator end = OutputList.end(); - for (; i != end; ++i) { - Output *output = *i; - if (!output->valid()) - continue; - - output->output(); + if (repeat) + new _StatEvent(dump, reset, curTick + repeat, repeat); } -} +}; void -SetupEvent(int flags, Tick when, Tick repeat, EventQueue *queue) +StatEvent(bool dump, bool reset, Tick when, Tick repeat) { - if (queue == NULL) - queue = &mainEventQueue; - - new StatEvent(queue, flags, when, repeat); + new _StatEvent(dump, reset, when, repeat); } /* namespace Stats */ } - -void debugDumpStats() -{ - Stats::DumpNow(); -} - diff --git a/src/sim/stat_control.hh b/src/sim/stat_control.hh index 67f7cc491..1efa2554e 100644 --- a/src/sim/stat_control.hh +++ b/src/sim/stat_control.hh @@ -31,25 +31,10 @@ #ifndef __SIM_STAT_CONTROL_HH__ #define __SIM_STAT_CONTROL_HH__ -#include -#include - -class EventQueue; - namespace Stats { -enum { - Reset = 0x1, - Dump = 0x2 -}; - -class Output; -extern std::list OutputList; - -void DumpNow(); -void SetupEvent(int flags, Tick when, Tick repeat = 0, EventQueue *queue = NULL); - -void InitSimStats(); +void initSimStats(); +void StatEvent(bool dump, bool reset, Tick when = curTick, Tick repeat = 0); /* namespace Stats */ } -- 2.30.2