summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/ev5.cc3
-rw-r--r--base/stats/events.cc121
-rw-r--r--base/stats/events.hh2
-rw-r--r--base/stats/mysql.cc14
-rw-r--r--base/stats/mysql_run.hh7
-rw-r--r--cpu/simple_cpu/simple_cpu.cc4
-rw-r--r--dev/disk_image.cc3
-rw-r--r--dev/ns_gige.cc27
-rw-r--r--dev/uart.cc97
-rw-r--r--dev/uart.hh6
-rw-r--r--sim/serialize.cc2
-rw-r--r--sim/serialize.hh2
-rw-r--r--sim/sim_object.cc9
-rw-r--r--sim/sim_object.hh4
14 files changed, 226 insertions, 75 deletions
diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc
index d2ca71b3a..b043ed0ee 100644
--- a/arch/alpha/ev5.cc
+++ b/arch/alpha/ev5.cc
@@ -6,6 +6,7 @@
#include "base/kgdb.h"
#include "base/remote_gdb.hh"
#include "base/stats/events.hh"
+#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "cpu/fast_cpu/fast_cpu.hh"
#include "sim/debug.hh"
@@ -163,7 +164,7 @@ void
ExecContext::ev5_trap(Fault fault)
{
DPRINTF(Fault, "Fault %s\n", FaultName(fault));
- Stats::recordEvent(csprintf("Fault %s", FaultName(fault)));
+ cpu->recordEvent(csprintf("Fault %s", FaultName(fault)));
assert(!misspeculating());
kernelStats.fault(fault);
diff --git a/base/stats/events.cc b/base/stats/events.cc
index b579981e9..ed25e2423 100644
--- a/base/stats/events.cc
+++ b/base/stats/events.cc
@@ -26,6 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <vector>
+
#ifdef USE_MYSQL
#include "base/cprintf.hh"
#include "base/misc.hh"
@@ -33,9 +35,9 @@
#include "base/stats/events.hh"
#include "base/stats/mysql.hh"
#include "base/stats/mysql_run.hh"
-#include "base/str.hh"
#endif
+#include "base/str.hh"
#include "sim/host.hh"
#include "sim/universe.hh"
@@ -45,20 +47,80 @@ namespace Stats {
Tick EventStart = ULL(0xffffffffffffffff);
+vector<string> event_ignore;
+vector<vector<string> > ignore_tokens;
+vector<int> ignore_size;
+int event_ignore_size;
+
+bool
+ignoreEvent(const string &name)
+{
+ vector<string> name_tokens;
+ tokenize(name_tokens, name, '.');
+ int ntsize = name_tokens.size();
+
+ for (int i = 0; i < event_ignore_size; ++i) {
+ bool match = true;
+ int jstop = ignore_size[i];
+ for (int j = 0; j < jstop; ++j) {
+ if (j >= ntsize)
+ break;
+
+ const string &ignore = ignore_tokens[i][j];
+ if (ignore != "*" && ignore != name_tokens[j]) {
+ match = false;
+ break;
+ }
+ }
+
+ if (match == true)
+ return true;
+ }
+
+ return false;
+}
+
#ifdef USE_MYSQL
-typedef map<string, uint32_t> event_map_t;
-event_map_t event_map;
+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
-__event(const string &stat)
+InsertEvent::insert(const string &stat)
{
- MySQL::Connection &mysql = MySqlDB.conn();
- uint16_t run = MySqlDB.run();
assert(mysql.connected());
- event_map_t::iterator i = event_map.find(stat);
+ event_map_t::iterator i = events.find(stat);
uint32_t event;
- if (i == event_map.end()) {
+ if (i == events.end()) {
mysql.query(
csprintf("SELECT en_id "
"from event_names "
@@ -90,16 +152,45 @@ __event(const string &stat)
event = (*i).second;
}
- mysql.query(
- csprintf("INSERT INTO "
- "events(ev_event, ev_run, ev_tick)"
- "values(%d, %d, %d)",
- event, run, curTick));
+ if (size + 1024 > maxsize)
+ flush();
+
+ if (!first) {
+ query[size++] = ',';
+ query[size] = '\0';
+ }
- if (mysql.error)
- panic("could not get a run\n%s\n", mysql.error);
+ first = false;
+ size += sprintf(query + size, "(%u,%u,%llu)",
+ event, run, curTick);
}
+
+void
+InsertEvent::flush()
+{
+ if (size) {
+ MySQL::Connection &mysql = MySqlDB.conn();
+ assert(mysql.connected());
+ mysql.query(query);
+ }
+
+ query[0] = '\0';
+ size = 0;
+ first = true;
+ strcpy(query, "INSERT INTO "
+ "events(ev_event, ev_run, ev_tick)"
+ "values");
+ size = strlen(query);
+}
+
+void
+__event(const string &stat)
+{
+ static InsertEvent event;
+ event.insert(stat);
+}
+
#endif
/* namespace Stats */ }
diff --git a/base/stats/events.hh b/base/stats/events.hh
index 49c060645..3a7d85644 100644
--- a/base/stats/events.hh
+++ b/base/stats/events.hh
@@ -42,6 +42,8 @@ void __event(const std::string &stat);
bool MySqlConnected();
#endif
+bool ignoreEvent(const std::string &name);
+
inline void
recordEvent(const std::string &stat)
{
diff --git a/base/stats/mysql.cc b/base/stats/mysql.cc
index 42f68811b..4c2a60127 100644
--- a/base/stats/mysql.cc
+++ b/base/stats/mysql.cc
@@ -57,7 +57,8 @@ MySqlConnected()
void
MySqlRun::connect(const string &host, const string &user, const string &passwd,
- const string &db, const string &name, const string &project)
+ const string &db, const string &name, const string &sample,
+ const string &project)
{
if (connected())
panic("can only get one database connection at this time!");
@@ -68,21 +69,22 @@ MySqlRun::connect(const string &host, const string &user, const string &passwd,
remove(name);
cleanup();
- setup(name, user, project);
+ setup(name, sample, user, project);
}
void
-MySqlRun::setup(const string &name, const string &user, const string &project)
+MySqlRun::setup(const string &name, const string &sample, const string &user,
+ const string &project)
{
assert(mysql.connected());
stringstream insert;
ccprintf(insert,
"INSERT INTO "
- "runs(rn_name, rn_user, rn_project, rn_date, rn_expire)"
- "values(\"%s\", \"%s\", \"%s\", NOW(),"
+ "runs(rn_name,rn_sample,rn_user,rn_project,rn_date,rn_expire)"
+ "values(\"%s\", \"%s\", \"%s\", \"%s\", NOW(),"
"DATE_ADD(CURDATE(), INTERVAL 31 DAY))",
- name, user, project);
+ name, sample, user, project);
mysql.query(insert);
if (mysql.error)
diff --git a/base/stats/mysql_run.hh b/base/stats/mysql_run.hh
index 0f8d84297..3e19a184e 100644
--- a/base/stats/mysql_run.hh
+++ b/base/stats/mysql_run.hh
@@ -46,10 +46,11 @@ struct MySqlRun
bool connected() const { return mysql.connected(); }
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 &project);
+ const std::string &name, const std::string &sample,
+ const std::string &project);
- void setup(const std::string &name, const std::string &user,
- const std::string &project);
+ void setup(const std::string &name, const std::string &sample,
+ const std::string &user, const std::string &project);
void remove(const std::string &name);
void cleanup();
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index 8ed2247ae..d70f0ccfa 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -406,7 +406,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
}
if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
- Stats::recordEvent("Uncached Read");
+ recordEvent("Uncached Read");
return fault;
}
@@ -494,7 +494,7 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
*res = memReq->result;
if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
- Stats::recordEvent("Uncached Write");
+ recordEvent("Uncached Write");
return fault;
}
diff --git a/dev/disk_image.cc b/dev/disk_image.cc
index d990d7078..f9e1c2fe3 100644
--- a/dev/disk_image.cc
+++ b/dev/disk_image.cc
@@ -425,7 +425,7 @@ CowDiskImage::write(const uint8_t *data, off_t offset)
void
CowDiskImage::serialize(ostream &os)
{
- string cowFilename = Checkpoint::dir() + name() + ".cow";
+ string cowFilename = name() + ".cow";
SERIALIZE_SCALAR(cowFilename);
save(cowFilename);
}
@@ -435,6 +435,7 @@ CowDiskImage::unserialize(Checkpoint *cp, const string &section)
{
string cowFilename;
UNSERIALIZE_SCALAR(cowFilename);
+ cowFilename = cp->cptDir + "/" + cowFilename;
open(cowFilename);
}
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index f3f2f10b3..64f255e6b 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -1780,7 +1780,8 @@ NSGigE::txKick()
udpChecksum(txPacket, true);
} else if (txDescCache.extsts & EXTSTS_TCPPKT) {
tcpChecksum(txPacket, true);
- } else if (txDescCache.extsts & EXTSTS_IPPKT) {
+ }
+ if (txDescCache.extsts & EXTSTS_IPPKT) {
ipChecksum(txPacket, true);
}
}
@@ -2043,15 +2044,25 @@ NSGigE::tcpChecksum(PacketPtr packet, bool gen)
ip_header *ip = packet->getIpHdr();
tcp_header *hdr = packet->getTcpHdr(ip);
+ uint16_t cksum;
pseudo_header *pseudo = new pseudo_header;
+ if (!gen) {
+ pseudo->src_ip_addr = ip->src_ip_addr;
+ pseudo->dest_ip_addr = ip->dest_ip_addr;
+ pseudo->protocol = reverseEnd16(ip->protocol);
+ pseudo->len = reverseEnd16(reverseEnd16(ip->dgram_len) - (ip->vers_len & 0xf)*4);
- pseudo->src_ip_addr = ip->src_ip_addr;
- pseudo->dest_ip_addr = ip->dest_ip_addr;
- pseudo->protocol = reverseEnd16(ip->protocol);
- pseudo->len = reverseEnd16(reverseEnd16(ip->dgram_len) - (ip->vers_len & 0xf)*4);
-
- uint16_t cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr,
+ cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr,
(uint32_t) reverseEnd16(pseudo->len));
+ } else {
+ pseudo->src_ip_addr = 0;
+ pseudo->dest_ip_addr = 0;
+ pseudo->protocol = hdr->chksum;
+ pseudo->len = 0;
+ hdr->chksum = 0;
+ cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr,
+ (uint32_t) (reverseEnd16(ip->dgram_len) - (ip->vers_len & 0xf)*4));
+ }
delete pseudo;
if (gen)
@@ -2071,7 +2082,7 @@ NSGigE::ipChecksum(PacketPtr packet, bool gen)
uint16_t cksum = checksumCalc(NULL, (uint16_t *) hdr, (hdr->vers_len & 0xf)*4);
if (gen) {
- DPRINTF(Ethernet, "generated checksum: %#x\n", cksum);
+ DPRINTF(EthernetCksum, "generated checksum: %#x\n", cksum);
hdr->hdr_chksum = cksum;
}
else
diff --git a/dev/uart.cc b/dev/uart.cc
index 30dde1984..4784ad640 100644
--- a/dev/uart.cc
+++ b/dev/uart.cc
@@ -48,10 +48,11 @@
using namespace std;
-Uart::IntrEvent::IntrEvent(Uart *u)
+Uart::IntrEvent::IntrEvent(Uart *u, int bit)
: Event(&mainEventQueue), uart(u)
{
DPRINTF(Uart, "UART Interrupt Event Initilizing\n");
+ intrBit = bit;
}
const char *
@@ -63,10 +64,10 @@ Uart::IntrEvent::description()
void
Uart::IntrEvent::process()
{
- if (UART_IER_THRI & uart->IER) {
+ if (intrBit & uart->IER) {
DPRINTF(Uart, "UART InterEvent, interrupting\n");
uart->platform->postConsoleInt();
- uart->status |= TX_INT;
+ uart->status |= intrBit;
}
else
DPRINTF(Uart, "UART InterEvent, not interrupting\n");
@@ -76,16 +77,20 @@ Uart::IntrEvent::process()
void
Uart::IntrEvent::scheduleIntr()
{
- DPRINTF(Uart, "Scheduling IER interrupt\n");
+ DPRINTF(Uart, "Scheduling IER interrupt for %#x, at cycle %lld\n", intrBit,
+ curTick + (ticksPerSecond/2000) * 350);
if (!scheduled())
- schedule(curTick + 300);
+ /* @todo Make this cleaner, will be much easier with
+ * nanosecond time everywhere. Hint hint Nate. */
+ schedule(curTick + (ticksPerSecond/2000000000) * 450);
else
- reschedule(curTick + 300);
+ reschedule(curTick + (ticksPerSecond/2000000000) * 450);
}
Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
Addr s, HierParams *hier, Bus *bus, Platform *p)
- : PioDevice(name), addr(a), size(s), cons(c), intrEvent(this), platform(p)
+ : PioDevice(name), addr(a), size(s), cons(c), txIntrEvent(this, TX_INT),
+ rxIntrEvent(this, RX_INT), platform(p)
{
mmu->add_child(this, Range<Addr>(addr, addr + size));
@@ -177,7 +182,6 @@ Uart::read(MemReqPtr &req, uint8_t *data)
switch (daddr) {
case 0x0:
if (!(LCR & 0x80)) { // read byte
- //assert(cons->dataAvailable());
if (cons->dataAvailable())
cons->in(*data);
else {
@@ -185,14 +189,11 @@ Uart::read(MemReqPtr &req, uint8_t *data)
// A limited amount of these are ok.
DPRINTF(Uart, "empty read of RX register\n");
}
+ status &= ~RX_INT;
+ platform->clearConsoleInt();
- if (cons->dataAvailable())
- platform->postConsoleInt();
- else
- {
- status &= ~RX_INT;
- platform->clearConsoleInt();
- }
+ if (cons->dataAvailable() && (IER & UART_IER_RDI))
+ rxIntrEvent.scheduleIntr();
} else { // dll divisor latch
;
}
@@ -205,10 +206,11 @@ Uart::read(MemReqPtr &req, uint8_t *data)
}
break;
case 0x2: // Intr Identification Register (IIR)
+ DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
if (status)
- *(uint8_t*)data = 1;
- else
*(uint8_t*)data = 0;
+ else
+ *(uint8_t*)data = 1;
break;
case 0x3: // Line Control Register (LCR)
*(uint8_t*)data = LCR;
@@ -288,7 +290,7 @@ Uart::write(MemReqPtr &req, const uint8_t *data)
platform->clearConsoleInt();
status &= ~TX_INT;
if (UART_IER_THRI & IER)
- intrEvent.scheduleIntr();
+ txIntrEvent.scheduleIntr();
} else { // dll divisor latch
;
}
@@ -296,19 +298,32 @@ Uart::write(MemReqPtr &req, const uint8_t *data)
case 0x1:
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
IER = *(uint8_t*)data;
- if ((UART_IER_THRI & IER) || ((UART_IER_RDI & IER) && cons->dataAvailable()))
- platform->postConsoleInt();
- else
+ if (UART_IER_THRI & IER)
{
- platform->clearConsoleInt();
- if (intrEvent.scheduled())
- intrEvent.deschedule();
-
+ DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n");
+ txIntrEvent.scheduleIntr();
}
- if (!(UART_IER_THRI & IER))
+ else
+ {
+ DPRINTF(Uart, "IER: IER_THRI cleared, descheduling TX intrrupt\n");
+ if (txIntrEvent.scheduled())
+ txIntrEvent.deschedule();
+ if (status & TX_INT)
+ platform->clearConsoleInt();
status &= ~TX_INT;
- if (!((UART_IER_RDI & IER) && cons->dataAvailable()))
+ }
+
+ if ((UART_IER_RDI & IER) && cons->dataAvailable()) {
+ DPRINTF(Uart, "IER: IER_RDI set, scheduling RX intrrupt\n");
+ rxIntrEvent.scheduleIntr();
+ } else {
+ DPRINTF(Uart, "IER: IER_RDI cleared, descheduling RX intrrupt\n");
+ if (rxIntrEvent.scheduled())
+ rxIntrEvent.deschedule();
+ if (status & RX_INT)
+ platform->clearConsoleInt();
status &= ~RX_INT;
+ }
} else { // DLM divisor latch MSB
;
}
@@ -370,12 +385,18 @@ Uart::serialize(ostream &os)
SERIALIZE_SCALAR(DLAB);
SERIALIZE_SCALAR(LCR);
SERIALIZE_SCALAR(MCR);
- Tick intrwhen;
- if (intrEvent.scheduled())
- intrwhen = intrEvent.when();
+ Tick rxintrwhen;
+ if (rxIntrEvent.scheduled())
+ rxintrwhen = rxIntrEvent.when();
+ else
+ rxintrwhen = 0;
+ Tick txintrwhen;
+ if (txIntrEvent.scheduled())
+ txintrwhen = txIntrEvent.when();
else
- intrwhen = 0;
- SERIALIZE_SCALAR(intrwhen);
+ rxintrwhen = 0;
+ SERIALIZE_SCALAR(rxintrwhen);
+ SERIALIZE_SCALAR(txintrwhen);
#endif
}
@@ -391,10 +412,14 @@ Uart::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(DLAB);
UNSERIALIZE_SCALAR(LCR);
UNSERIALIZE_SCALAR(MCR);
- Tick intrwhen;
- UNSERIALIZE_SCALAR(intrwhen);
- if (intrwhen != 0)
- intrEvent.schedule(intrwhen);
+ Tick rxintrwhen;
+ Tick txintrwhen;
+ UNSERIALIZE_SCALAR(rxintrwhen);
+ UNSERIALIZE_SCALAR(txintrwhen);
+ if (rxintrwhen != 0)
+ rxIntrEvent.schedule(rxintrwhen);
+ if (txintrwhen != 0)
+ txIntrEvent.schedule(txintrwhen);
#endif
}
diff --git a/dev/uart.hh b/dev/uart.hh
index 83e1a758c..07ad4d0c8 100644
--- a/dev/uart.hh
+++ b/dev/uart.hh
@@ -62,14 +62,16 @@ class Uart : public PioDevice
{
protected:
Uart *uart;
+ int intrBit;
public:
- IntrEvent(Uart *u);
+ IntrEvent(Uart *u, int bit);
virtual void process();
virtual const char *description();
void scheduleIntr();
};
- IntrEvent intrEvent;
+ IntrEvent txIntrEvent;
+ IntrEvent rxIntrEvent;
Platform *platform;
public:
diff --git a/sim/serialize.cc b/sim/serialize.cc
index 945f97c06..91548f653 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -431,7 +431,7 @@ Serializable::create(Checkpoint *cp, const std::string &section)
Checkpoint::Checkpoint(const std::string &cpt_dir, const std::string &path,
const ConfigNode *_configNode)
- : db(new IniFile), basePath(path), configNode(_configNode)
+ : db(new IniFile), basePath(path), configNode(_configNode), cptDir(cpt_dir)
{
string filename = cpt_dir + "/" + Checkpoint::baseFilename;
if (!db->load(filename)) {
diff --git a/sim/serialize.hh b/sim/serialize.hh
index ad490d616..5df168665 100644
--- a/sim/serialize.hh
+++ b/sim/serialize.hh
@@ -210,6 +210,8 @@ class Checkpoint
Checkpoint(const std::string &cpt_dir, const std::string &path,
const ConfigNode *_configNode);
+ const std::string cptDir;
+
bool find(const std::string &section, const std::string &entry,
std::string &value);
diff --git a/sim/sim_object.cc b/sim/sim_object.cc
index cab629f8d..39219b500 100644
--- a/sim/sim_object.cc
+++ b/sim/sim_object.cc
@@ -32,6 +32,7 @@
#include "base/inifile.hh"
#include "base/misc.hh"
#include "base/trace.hh"
+#include "base/stats/events.hh"
#include "sim/configfile.hh"
#include "sim/host.hh"
#include "sim/sim_object.hh"
@@ -58,6 +59,7 @@ SimObject::SimObjectList SimObject::simObjectList;
SimObject::SimObject(const string &_name)
: objName(_name)
{
+ doRecordEvent = !Stats::ignoreEvent(_name);
simObjectList.push_back(this);
}
@@ -170,4 +172,11 @@ SimObject::serializeAll(ostream &os)
}
}
+void
+SimObject::recordEvent(const std::string &stat)
+{
+ if (doRecordEvent)
+ Stats::recordEvent(stat);
+}
+
DEFINE_SIM_OBJECT_CLASS_NAME("SimObject", SimObject)
diff --git a/sim/sim_object.hh b/sim/sim_object.hh
index 1a9ed363d..770cd558e 100644
--- a/sim/sim_object.hh
+++ b/sim/sim_object.hh
@@ -82,6 +82,10 @@ class SimObject : public Serializable
// static: call nameOut() & serialize() on all SimObjects
static void serializeAll(std::ostream &);
+
+ public:
+ bool doRecordEvent;
+ void recordEvent(const std::string &stat);
};
#endif // __SIM_OBJECT_HH__