diff options
Diffstat (limited to 'src/base/stats')
-rw-r--r-- | src/base/stats/events.cc | 131 | ||||
-rw-r--r-- | src/base/stats/events.hh | 10 | ||||
-rw-r--r-- | src/base/stats/mysql.cc | 253 | ||||
-rw-r--r-- | src/base/stats/mysql.hh | 60 | ||||
-rw-r--r-- | src/base/stats/output.cc | 70 | ||||
-rw-r--r-- | src/base/stats/output.hh | 1 | ||||
-rw-r--r-- | src/base/stats/text.cc | 22 | ||||
-rw-r--r-- | src/base/stats/text.hh | 6 |
8 files changed, 354 insertions, 199 deletions
diff --git a/src/base/stats/events.cc b/src/base/stats/events.cc index 6ecc5434c..dc56fe75f 100644 --- a/src/base/stats/events.cc +++ b/src/base/stats/events.cc @@ -31,20 +31,8 @@ #include <vector> #include "base/stats/events.hh" - -#if USE_MYSQL -#include "base/cprintf.hh" -#include "base/misc.hh" -#include "base/mysql.hh" -#include "base/stats/mysql.hh" -#include "base/stats/mysql_run.hh" -#include "base/str.hh" -#endif - -#include "base/match.hh" +#include "base/stats/output.hh" #include "sim/host.hh" -#include "sim/sim_object.hh" -#include "sim/root.hh" using namespace std; @@ -52,118 +40,21 @@ namespace Stats { Tick EventStart = ULL(0x7fffffffffffffff); -ObjectMatch event_ignore; +extern list<Output *> OutputList; #if USE_MYSQL -class InsertEvent -{ - private: - char *query; - int size; - bool first; - static const int maxsize = 1024*1024; - - typedef map<string, uint32_t> event_map_t; - event_map_t events; - - MySQL::Connection &mysql; - uint16_t run; - - public: - InsertEvent() - : mysql(MySqlDB.conn()), run(MySqlDB.run()) - { - query = new char[maxsize + 1]; - size = 0; - first = true; - flush(); - } - ~InsertEvent() - { - flush(); - } - - void flush(); - void insert(const string &stat); -}; - void -InsertEvent::insert(const string &stat) +__event(const string &event) { - assert(mysql.connected()); - - event_map_t::iterator i = events.find(stat); - uint32_t event; - if (i == events.end()) { - mysql.query( - csprintf("SELECT en_id " - "from event_names " - "where en_name=\"%s\"", - stat)); - - MySQL::Result result = mysql.store_result(); - if (!result) - panic("could not get a run\n%s\n", mysql.error); - - assert(result.num_fields() == 1); - MySQL::Row row = result.fetch_row(); - if (row) { - if (!to_number(row[0], event)) - panic("invalid event id: %s\n", row[0]); - } else { - mysql.query( - csprintf("INSERT INTO " - "event_names(en_name)" - "values(\"%s\")", - stat)); - - if (mysql.error) - panic("could not get a run\n%s\n", mysql.error); - - event = mysql.insert_id(); - } - } else { - event = (*i).second; + list<Output *>::iterator i = OutputList.begin(); + list<Output *>::iterator end = OutputList.end(); + for (; i != end; ++i) { + Output *output = *i; + if (!output->valid()) + continue; + + output->event(event); } - - if (size + 1024 > maxsize) - flush(); - - if (!first) { - query[size++] = ','; - query[size] = '\0'; - } - - first = false; - - size += sprintf(query + size, "(%u,%u,%llu)", - event, run, (unsigned long long)curTick); -} - -void -InsertEvent::flush() -{ - static const char query_header[] = "INSERT INTO " - "events(ev_event, ev_run, ev_tick)" - "values"; - - if (size) { - MySQL::Connection &mysql = MySqlDB.conn(); - assert(mysql.connected()); - mysql.query(query); - } - - query[0] = '\0'; - size = sizeof(query_header); - first = true; - memcpy(query, query_header, size); -} - -void -__event(const string &stat) -{ - static InsertEvent event; - event.insert(stat); } #endif diff --git a/src/base/stats/events.hh b/src/base/stats/events.hh index b09b91c7c..8ba9cece5 100644 --- a/src/base/stats/events.hh +++ b/src/base/stats/events.hh @@ -42,11 +42,10 @@ extern Tick EventStart; #if USE_MYSQL void __event(const std::string &stat); -bool MySqlConnected(); +#else +inline void __event(const std::string &stat) {} #endif -bool ignoreEvent(const std::string &name); - inline void recordEvent(const std::string &stat) { @@ -55,12 +54,7 @@ recordEvent(const std::string &stat) DPRINTF(StatEvents, "Statistics Event: %s\n", stat); -#if USE_MYSQL - if (!MySqlConnected()) - return; - __event(stat); -#endif } /* namespace Stats */ } diff --git a/src/base/stats/mysql.cc b/src/base/stats/mysql.cc index 0fb31f4ce..39a687fff 100644 --- a/src/base/stats/mysql.cc +++ b/src/base/stats/mysql.cc @@ -43,20 +43,13 @@ #include "base/stats/statdb.hh" #include "base/stats/types.hh" #include "base/str.hh" +#include "base/userinfo.hh" #include "sim/host.hh" 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, @@ -196,9 +189,9 @@ SetupStat::init() } unsigned -SetupStat::setup() +SetupStat::setup(MySqlRun *run) { - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); stringstream insert; ccprintf(insert, @@ -301,7 +294,8 @@ SetupStat::setup() return statid; } -InsertData::InsertData() +InsertData::InsertData(MySqlRun *_run) + : run(_run) { query = new char[maxsize + 1]; size = 0; @@ -317,7 +311,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,10 +343,97 @@ 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); } +InsertEvent::InsertEvent(MySqlRun *_run) + : run(_run) +{ + query = new char[maxsize + 1]; + size = 0; + first = true; + flush(); +} + +InsertEvent::~InsertEvent() +{ + flush(); +} + +void +InsertEvent::insert(const string &stat) +{ + MySQL::Connection &mysql = run->conn(); + assert(mysql.connected()); + + event_map_t::iterator i = events.find(stat); + uint32_t event; + if (i == events.end()) { + mysql.query( + csprintf("SELECT en_id " + "from event_names " + "where en_name=\"%s\"", + stat)); + + MySQL::Result result = mysql.store_result(); + if (!result) + panic("could not get a run\n%s\n", mysql.error); + + assert(result.num_fields() == 1); + MySQL::Row row = result.fetch_row(); + if (row) { + if (!to_number(row[0], event)) + panic("invalid event id: %s\n", row[0]); + } else { + mysql.query( + csprintf("INSERT INTO " + "event_names(en_name)" + "values(\"%s\")", + stat)); + + if (mysql.error) + panic("could not get a run\n%s\n", mysql.error); + + event = mysql.insert_id(); + } + } else { + event = (*i).second; + } + + if (size + 1024 > maxsize) + flush(); + + if (!first) { + query[size++] = ','; + query[size] = '\0'; + } + + first = false; + + size += sprintf(query + size, "(%u,%u,%llu)", + event, run->run(), (unsigned long long)curTick); +} + +void +InsertEvent::flush() +{ + static const char query_header[] = "INSERT INTO " + "events(ev_event, ev_run, ev_tick)" + "values"; + + MySQL::Connection &mysql = run->conn(); + assert(mysql.connected()); + + if (size) + mysql.query(query); + + query[0] = '\0'; + size = sizeof(query_header); + first = true; + memcpy(query, query_header, size); +} + struct InsertSubData { uint16_t stat; @@ -361,13 +442,13 @@ struct InsertSubData string name; string descr; - void setup(); + void setup(MySqlRun *run); }; void -InsertSubData::setup() +InsertSubData::setup(MySqlRun *run) { - MySQL::Connection &mysql = MySqlDB.conn(); + MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); stringstream insert; ccprintf(insert, @@ -383,47 +464,27 @@ InsertSubData::setup() panic("could not commit transaction\n%s\n", mysql.error); } -void -InsertFormula(uint16_t stat, const string &formula) -{ - MySQL::Connection &mysql = MySqlDB.conn(); - assert(mysql.connected()); - stringstream insert_formula; - ccprintf(insert_formula, - "INSERT INTO formulas(fm_stat,fm_formula) values(%d, \"%s\")", - stat, formula); +MySql::MySql() + : run(new MySqlRun), newdata(run), newevent(run) +{} - mysql.query(insert_formula); -// if (mysql.error) -// panic("could not insert formula\n%s\n", mysql.error); - - stringstream insert_ref; - ccprintf(insert_ref, - "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)", - stat, MySqlDB.run()); - - mysql.query(insert_ref); -// if (mysql.error) -// panic("could not insert formula reference\n%s\n", mysql.error); - - if (mysql.commit()) - panic("could not commit transaction\n%s\n", mysql.error); +MySql::~MySql() +{ + delete run; } void -UpdatePrereq(uint16_t stat, uint16_t prereq) +MySql::connect(const string &host, const string &user, const string &passwd, + const string &db, const string &name, const string &sample, + const string &project) { - MySQL::Connection &mysql = MySqlDB.conn(); - assert(mysql.connected()); - stringstream update; - ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d", - prereq, stat); - mysql.query(update); - if (mysql.error) - panic("could not update prereq\n%s\n", mysql.error); + run->connect(host, user, passwd, db, name, sample, project); +} - if (mysql.commit()) - panic("could not commit transaction\n%s\n", mysql.error); +bool +MySql::connected() const +{ + return run->connected(); } void @@ -434,7 +495,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) { @@ -444,11 +505,20 @@ MySql::configure() for (i = stats().begin(); i != end; ++i) { StatData *data = *i; if (data->prereq) { + // update the prerequisite uint16_t stat_id = find(data->id); uint16_t prereq_id = find(data->prereq->id); assert(stat_id && prereq_id); - UpdatePrereq(stat_id, prereq_id); + stringstream update; + ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d", + prereq_id, stat_id); + mysql.query(update); + if (mysql.error) + panic("could not update prereq\n%s\n", mysql.error); + + if (mysql.commit()) + panic("could not commit transaction\n%s\n", mysql.error); } } @@ -483,7 +553,7 @@ MySql::configure(const ScalarData &data) if (!configure(data, "SCALAR")) return; - insert(data.id, stat.setup()); + insert(data.id, stat.setup(run)); } void @@ -492,7 +562,7 @@ MySql::configure(const VectorData &data) if (!configure(data, "VECTOR")) return; - uint16_t statid = stat.setup(); + uint16_t statid = stat.setup(run); if (!data.subnames.empty()) { InsertSubData subdata; @@ -504,7 +574,7 @@ MySql::configure(const VectorData &data) subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) - subdata.setup(); + subdata.setup(run); } } @@ -523,7 +593,7 @@ MySql::configure(const DistData &data) stat.max = data.data.max; stat.bktsize = data.data.bucket_size; } - insert(data.id, stat.setup()); + insert(data.id, stat.setup(run)); } void @@ -539,7 +609,7 @@ MySql::configure(const VectorDistData &data) stat.bktsize = data.data[0].bucket_size; } - uint16_t statid = stat.setup(); + uint16_t statid = stat.setup(run); if (!data.subnames.empty()) { InsertSubData subdata; @@ -550,7 +620,7 @@ MySql::configure(const VectorDistData &data) subdata.name = data.subnames[i]; subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) - subdata.setup(); + subdata.setup(run); } } @@ -563,7 +633,7 @@ MySql::configure(const Vector2dData &data) if (!configure(data, "VECTOR2D")) return; - uint16_t statid = stat.setup(); + uint16_t statid = stat.setup(run); if (!data.subnames.empty()) { InsertSubData subdata; @@ -574,7 +644,7 @@ MySql::configure(const Vector2dData &data) subdata.name = data.subnames[i]; subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) - subdata.setup(); + subdata.setup(run); } } @@ -587,7 +657,7 @@ MySql::configure(const Vector2dData &data) subdata.y = i; subdata.name = data.y_subnames[i]; if (!subdata.name.empty()) - subdata.setup(); + subdata.setup(run); } } @@ -597,15 +667,41 @@ MySql::configure(const Vector2dData &data) void MySql::configure(const FormulaData &data) { + MySQL::Connection &mysql = run->conn(); + assert(mysql.connected()); + configure(data, "FORMULA"); - insert(data.id, stat.setup()); - InsertFormula(find(data.id), data.str()); + insert(data.id, stat.setup(run)); + + uint16_t stat = find(data.id); + string formula = data.str(); + + stringstream insert_formula; + ccprintf(insert_formula, + "INSERT INTO formulas(fm_stat,fm_formula) values(%d, \"%s\")", + stat, formula); + + mysql.query(insert_formula); +// if (mysql.error) +// panic("could not insert formula\n%s\n", mysql.error); + + stringstream insert_ref; + ccprintf(insert_ref, + "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)", + stat, run->run()); + + mysql.query(insert_ref); +// if (mysql.error) +// panic("could not insert formula reference\n%s\n", mysql.error); + + if (mysql.commit()) + panic("could not commit transaction\n%s\n", mysql.error); } bool MySql::valid() const { - return MySqlDB.connected(); + return run->connected(); } void @@ -620,7 +716,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) { @@ -634,6 +730,13 @@ MySql::output() } void +MySql::event(const std::string &event) +{ + newevent.insert(event); +} + + +void MySql::output(const ScalarData &data) { if (!(data.flags & print)) @@ -825,4 +928,20 @@ MySql::visit(const FormulaData &data) output(data); } -/* namespace Stats */ } +bool +initMySQL(string host, string user, string password, string database, + string project, string name, string sample) +{ + extern list<Output *> OutputList; + static MySql mysql; + + if (mysql.connected()) + return false; + + mysql.connect(host, user, password, database, name, sample, project); + OutputList.push_back(&mysql); + + return true; +} + +/* end namespace Stats */ } diff --git a/src/base/stats/mysql.hh b/src/base/stats/mysql.hh index 50f7d9e97..0ce381c2f 100644 --- a/src/base/stats/mysql.hh +++ b/src/base/stats/mysql.hh @@ -35,14 +35,13 @@ #include <string> #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 { @@ -63,7 +62,7 @@ struct SetupStat uint16_t size; void init(); - unsigned setup(); + unsigned setup(MySqlRun *run); }; class InsertData @@ -85,18 +84,43 @@ class InsertData int16_t y; public: - InsertData(); + InsertData(MySqlRun *_run); ~InsertData(); void flush(); void insert(); }; +class InsertEvent +{ + private: + char *query; + int size; + bool first; + static const int maxsize = 1024*1024; + + typedef std::map<std::string, uint32_t> event_map_t; + event_map_t events; + + MySqlRun *run; + + public: + InsertEvent(MySqlRun *_run); + ~InsertEvent(); + + void flush(); + void insert(const std::string &stat); +}; + class MySql : public Output { protected: + MySqlRun *run; /* Hide the implementation so we don't have a + #include mess */ + SetupStat stat; InsertData newdata; + InsertEvent newevent; std::list<FormulaData *> formulas; bool configured; @@ -116,6 +140,17 @@ class MySql : public Output assert(i != idmap.end()); return (*i).second; } + + public: + MySql(); + ~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); @@ -129,6 +164,9 @@ class MySql : public Output virtual bool valid() const; virtual void output(); + // Implement Event Output + virtual void event(const std::string &event); + protected: // Output helper void output(const DistDataData &data); @@ -149,6 +187,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 project, std::string name, + std::string sample); + +#if !USE_MYSQL +inline bool +initMySQL(std::string host, std::string user, std::string password, + std::string database, std::string project, std::string name, + std::string sample) +{ + 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 <list> + +#include "base/stats/output.hh" +#include "sim/eventq.hh" +#include "sim/host.hh" + +using namespace std; + +namespace Stats { + +Tick lastDump(0); +list<Output *> OutputList; + +void +dump() +{ + assert(lastDump <= curTick); + if (lastDump == curTick) + return; + lastDump = curTick; + + list<Output *>::iterator i = OutputList.begin(); + list<Output *>::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/output.hh b/src/base/stats/output.hh index 4fe93791f..c7ffcaade 100644 --- a/src/base/stats/output.hh +++ b/src/base/stats/output.hh @@ -42,6 +42,7 @@ struct Output : public Visit inline void operator()() { output(); } virtual void output() = 0; virtual bool valid() const = 0; + virtual void event(const std::string &event) = 0; }; /* namespace Stats */ } diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc index ae0d65537..a018c4837 100644 --- a/src/base/stats/text.cc +++ b/src/base/stats/text.cc @@ -251,6 +251,7 @@ VectorPrint::operator()(std::ostream &stream) const ScalarPrint print; print.name = name; print.desc = desc; + print.compat = compat; print.precision = precision; print.descriptions = descriptions; print.flags = flags; @@ -725,4 +726,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<Output *> 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..781d1083d 100644 --- a/src/base/stats/text.hh +++ b/src/base/stats/text.hh @@ -34,6 +34,7 @@ #include <iosfwd> #include <string> +#include "base/output.hh" #include "base/stats/output.hh" namespace Stats { @@ -71,8 +72,13 @@ class Text : public Output // Implement Output virtual bool valid() const; virtual void output(); + + // Implement Event Output + virtual void event(const std::string &event) {} }; +bool initText(const std::string &filename, bool desc=true, bool compat=true); + /* namespace Stats */ } #endif // __BASE_STATS_TEXT_HH__ |