diff options
-rw-r--r-- | arch/alpha/ev5.cc | 3 | ||||
-rw-r--r-- | base/stats/events.cc | 121 | ||||
-rw-r--r-- | base/stats/events.hh | 2 | ||||
-rw-r--r-- | base/stats/mysql.cc | 14 | ||||
-rw-r--r-- | base/stats/mysql_run.hh | 7 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 4 | ||||
-rw-r--r-- | dev/disk_image.cc | 3 | ||||
-rw-r--r-- | dev/ns_gige.cc | 27 | ||||
-rw-r--r-- | dev/uart.cc | 97 | ||||
-rw-r--r-- | dev/uart.hh | 6 | ||||
-rw-r--r-- | sim/serialize.cc | 2 | ||||
-rw-r--r-- | sim/serialize.hh | 2 | ||||
-rw-r--r-- | sim/sim_object.cc | 9 | ||||
-rw-r--r-- | sim/sim_object.hh | 4 |
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 §ion) { 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 §ion) 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 §ion) 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 §ion, 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__ |