From 4c55d26e664f870d56889097939569c4b07c6de2 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 18 May 2004 16:09:02 -0700 Subject: Replace explicit xc->misspeculating() tests in execute() methods with an IsNonSpeculative flag. No effect on results of non-full-system or SimpleCPU. Very small impact on full-system FullCPU runs since old wrong-path call_pal insts used to change the PC, where now they're treated as no-ops. arch/alpha/isa_desc: Get rid of xc->misspeculating() checks, use IsNonSpeculative flag instead. cpu/static_inst.hh: Add IsNonSpeculative flag and isNonSpeculative() method to test it. --HG-- extra : convert_revision : 7ec536bfc28b905c429c09eb920ed73ef2beeeba --- arch/alpha/isa_desc | 151 ++++++++++++++++++++-------------------------------- cpu/static_inst.hh | 5 +- 2 files changed, 61 insertions(+), 95 deletions(-) diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc index f964101df..8641c2880 100644 --- a/arch/alpha/isa_desc +++ b/arch/alpha/isa_desc @@ -1374,8 +1374,8 @@ output decoder {{ } }}; -def format EmulatedCallPal(code) {{ - iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code)) +def format EmulatedCallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -1436,8 +1436,8 @@ output decoder {{ } }}; -def format CallPal(code) {{ - iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code)) +def format CallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -1588,6 +1588,9 @@ output header {{ FailUnimplemented(const char *_mnemonic, MachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1615,6 +1618,9 @@ output header {{ WarnUnimplemented(const char *_mnemonic, MachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1646,9 +1652,8 @@ output exec {{ FailUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - panic("attempt to execute unimplemented instruction '%s' " - "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); return Unimplemented_Opcode_Fault; } @@ -1656,42 +1661,24 @@ output exec {{ WarnUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - if (!warned) { - warn("instruction '%s' unimplemented\n", mnemonic); - warned = true; - } + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } return No_Fault; } }}; -def template WarnUnimplDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s - { - public: - /// Constructor - %(class_name)s(MachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst) - { - } - }; -}}; - - def format FailUnimpl() {{ iop = InstObjParams(name, 'FailUnimplemented') decode_block = BasicDecodeWithMnemonic.subst(iop) }}; def format WarnUnimpl() {{ - iop = InstObjParams(name, Name, 'WarnUnimplemented') - header_output = WarnUnimplDeclare.subst(iop) - decode_block = BasicDecode.subst(iop) + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) }}; output header {{ @@ -1707,6 +1694,9 @@ output header {{ Unknown(MachInst _machInst) : AlphaStaticInst("unknown", _machInst, No_OpClass) { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; } %(BasicExecDeclare)s @@ -1733,9 +1723,8 @@ output exec {{ Fault Unknown::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) { - if (!xc->misspeculating()) - panic("attempt to execute unknown instruction " - "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); return Unimplemented_Opcode_Fault; } }}; @@ -2420,16 +2409,12 @@ decode OPCODE default Unknown::unknown() { format BasicOperate { 0xe000: rc({{ Ra = xc->readIntrFlag(); - if (!xc->misspeculating()) { - xc->setIntrFlag(0); - } - }}); + xc->setIntrFlag(0); + }}, IsNonSpeculative); 0xf000: rs({{ Ra = xc->readIntrFlag(); - if (!xc->misspeculating()) { - xc->setIntrFlag(1); - } - }}); + xc->setIntrFlag(1); + }}, IsNonSpeculative); } #else format FailUnimpl { @@ -2449,38 +2434,26 @@ decode OPCODE default Unknown::unknown() { fault = Unimplemented_Opcode_Fault; } else { - bool dopal = true; - - if (!xc->misspeculating()) { - // check to see if simulator wants to do something special - // on this PAL call (including maybe suppress it) - dopal = xc->simPalCheck(palFunc); - - if (dopal) { - AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); - xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); - } - } + // check to see if simulator wants to do something special + // on this PAL call (including maybe suppress it) + bool dopal = xc->simPalCheck(palFunc); - // if we're misspeculating, it's still safe (if - // unrealistic) to set NPC, as the control-flow change - // won't get committed. if (dopal) { + AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); + xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; } } - }}); + }}, IsNonSpeculative); #else 0x00: decode PALFUNC { format EmulatedCallPal { 0x00: halt ({{ - if (!xc->misspeculating()) - SimExit(curTick, "halt instruction encountered"); - }}); + SimExit(curTick, "halt instruction encountered"); + }}, IsNonSpeculative); 0x83: callsys({{ - if (!xc->misspeculating()) - xc->syscall(); - }}); + xc->syscall(); + }}, IsNonSpeculative); // Read uniq reg into ABI return value register (r0) 0x9e: rduniq({{ R0 = Runiq; }}); // Write uniq reg with value from ABI arg register (r16) @@ -2514,46 +2487,36 @@ decode OPCODE default Unknown::unknown() { // M5 special opcodes use the reserved 0x01 opcode space 0x01: decode M5FUNC { 0x00: arm({{ - if (!xc->misspeculating()) - AlphaPseudo::arm(xc->xcBase()); - }}); + AlphaPseudo::arm(xc->xcBase()); + }}, IsNonSpeculative); 0x01: quiesce({{ - if (!xc->misspeculating()) - AlphaPseudo::quiesce(xc->xcBase()); - }}); + AlphaPseudo::quiesce(xc->xcBase()); + }}, IsNonSpeculative); 0x10: ivlb({{ - if (!xc->misspeculating()) - AlphaPseudo::ivlb(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::ivlb(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x11: ivle({{ - if (!xc->misspeculating()) - AlphaPseudo::ivle(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::ivle(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x20: m5exit_old({{ - if (!xc->misspeculating()) - AlphaPseudo::m5exit_old(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::m5exit_old(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x21: m5exit({{ - if (!xc->misspeculating()) - AlphaPseudo::m5exit(xc->xcBase()); - }}, No_OpClass); + AlphaPseudo::m5exit(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); 0x40: resetstats({{ - if (!xc->misspeculating()) - AlphaPseudo::resetstats(xc->xcBase()); - }}); + AlphaPseudo::resetstats(xc->xcBase()); + }}, IsNonSpeculative); 0x41: dumpstats({{ - if (!xc->misspeculating()) - AlphaPseudo::dumpstats(xc->xcBase()); - }}); + AlphaPseudo::dumpstats(xc->xcBase()); + }}, IsNonSpeculative); 0x42: dumpresetstats({{ - if (!xc->misspeculating()) - AlphaPseudo::dumpresetstats(xc->xcBase()); - }}); + AlphaPseudo::dumpresetstats(xc->xcBase()); + }}, IsNonSpeculative); 0x43: m5checkpoint({{ - if (!xc->misspeculating()) - AlphaPseudo::m5checkpoint(xc->xcBase()); - }}); + AlphaPseudo::m5checkpoint(xc->xcBase()); + }}, IsNonSpeculative); } } diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 1065fa3d4..088fdbdb7 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -106,11 +106,13 @@ class StaticInstBase : public RefCounted IsThreadSync, ///< Thread synchronization operation. - IsSerializing, ///< Serializes pipeline: won't until all + IsSerializing, ///< Serializes pipeline: won't execute until all /// older instructions have committed. IsMemBarrier, ///< Is a memory barrier IsWriteBarrier, ///< Is a write barrier + IsNonSpeculative, ///< Should not be executed speculatively + NumFlags }; @@ -192,6 +194,7 @@ class StaticInstBase : public RefCounted bool isSerializing() const { return flags[IsSerializing]; } bool isMemBarrier() const { return flags[IsMemBarrier]; } bool isWriteBarrier() const { return flags[IsWriteBarrier]; } + bool isNonSpeculative() const { return flags[IsNonSpeculative]; } //@} /// Operation class. Used to select appropriate function unit in issue. -- cgit v1.2.3 From 27a6e8258dabef233bc1681649b871bf150878ed Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 18 May 2004 22:09:13 -0700 Subject: Add a level of indirection to the register accessors used in instruction execute methods. Register i now means the instruction's i'th src (or dest) operand, not architectural register i. Current models that use the architectural reg index can look that up easily in the instruction object. Future models that do register renaming should find this much simpler to deal with. arch/isa_parser.py: Generate register accessors with an extra level of indirection. cpu/simple_cpu/simple_cpu.hh: Modify register accessors to use an extra level of indirection. --HG-- extra : convert_revision : f4c7d6bfa92fb2ea6251f31ee368809c3643f08f --- arch/isa_parser.py | 10 +++--- cpu/simple_cpu/simple_cpu.hh | 73 ++++++++++++++++++++++++++++++++------------ 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 621720709..7f77241be 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1057,10 +1057,10 @@ class IntRegOperandTraits(OperandTraits): if (type == 'float' or type == 'double'): error(0, 'Attempt to read integer register as FP') if (size == self.dflt_size): - return '%s = xc->readIntReg(_srcRegIdx[%d]);\n' % \ + return '%s = xc->readIntReg(this, %d);\n' % \ (op_desc.munged_name, op_desc.src_reg_idx) else: - return '%s = bits(xc->readIntReg(_srcRegIdx[%d]), %d, 0);\n' % \ + return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \ (op_desc.munged_name, op_desc.src_reg_idx, size-1) def makeWrite(self, op_desc): @@ -1074,7 +1074,7 @@ class IntRegOperandTraits(OperandTraits): wb = ''' { %s final_val = %s; - xc->setIntReg(_destRegIdx[%d], final_val);\n + xc->setIntReg(this, %d, final_val);\n if (traceData) { traceData->setData(final_val); } }''' % (self.dflt_type, final_val, op_desc.dest_reg_idx) return wb @@ -1107,7 +1107,7 @@ class FloatRegOperandTraits(OperandTraits): func = 'readFloatRegInt' if (size != self.dflt_size): bit_select = 1 - base = 'xc->%s(_srcRegIdx[%d] - FP_Base_DepTag)' % \ + base = 'xc->%s(this, %d)' % \ (func, op_desc.src_reg_idx) if bit_select: return '%s = bits(%s, %d, 0);\n' % \ @@ -1130,7 +1130,7 @@ class FloatRegOperandTraits(OperandTraits): wb = ''' { %s final_val = %s; - xc->%s(_destRegIdx[%d] - FP_Base_DepTag, final_val);\n + xc->%s(this, %d, final_val);\n if (traceData) { traceData->setData(final_val); } }''' % (type, final_val, func, op_desc.dest_reg_idx) return wb diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index a04dcd057..0c7204fcd 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -35,6 +35,7 @@ #include "cpu/pc_event.hh" #include "base/statistics.hh" #include "cpu/exec_context.hh" +#include "cpu/static_inst.hh" // forward declarations #ifdef FULL_SYSTEM @@ -261,37 +262,71 @@ class SimpleCPU : public BaseCPU Fault copy(Addr dest); - uint64_t readIntReg(int reg_idx) { return xc->readIntReg(reg_idx); } + // The register accessor methods provide the index of the + // instruction's operand (e.g., 0 or 1), not the architectural + // register index, to simplify the implementation of register + // renaming. We find the architectural register index by indexing + // into the instruction's own operand index table. Note that a + // raw pointer to the StaticInst is provided instead of a + // ref-counted StaticInstPtr to redice overhead. This is fine as + // long as these methods don't copy the pointer into any long-term + // storage (which is pretty hard to imagine they would have reason + // to do). + + uint64_t readIntReg(StaticInst *si, int idx) + { + return xc->readIntReg(si->srcRegIdx(idx)); + } - float readFloatRegSingle(int reg_idx) - { return xc->readFloatRegSingle(reg_idx); } + float readFloatRegSingle(StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegSingle(reg_idx); + } - double readFloatRegDouble(int reg_idx) - { return xc->readFloatRegDouble(reg_idx); } + double readFloatRegDouble(StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegDouble(reg_idx); + } - uint64_t readFloatRegInt(int reg_idx) - { return xc->readFloatRegInt(reg_idx); } + uint64_t readFloatRegInt(StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegInt(reg_idx); + } - void setIntReg(int reg_idx, uint64_t val) - { return xc->setIntReg(reg_idx, val); } + void setIntReg(StaticInst *si, int idx, uint64_t val) + { + xc->setIntReg(si->destRegIdx(idx), val); + } - void setFloatRegSingle(int reg_idx, float val) - { return xc->setFloatRegSingle(reg_idx, val); } + void setFloatRegSingle(StaticInst *si, int idx, float val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegSingle(reg_idx, val); + } - void setFloatRegDouble(int reg_idx, double val) - { return xc->setFloatRegDouble(reg_idx, val); } + void setFloatRegDouble(StaticInst *si, int idx, double val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegDouble(reg_idx, val); + } - void setFloatRegInt(int reg_idx, uint64_t val) - { return xc->setFloatRegInt(reg_idx, val); } + void setFloatRegInt(StaticInst *si, int idx, uint64_t val) + { + int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; + xc->setFloatRegInt(reg_idx, val); + } uint64_t readPC() { return xc->readPC(); } - void setNextPC(uint64_t val) { return xc->setNextPC(val); } + void setNextPC(uint64_t val) { xc->setNextPC(val); } uint64_t readUniq() { return xc->readUniq(); } - void setUniq(uint64_t val) { return xc->setUniq(val); } + void setUniq(uint64_t val) { xc->setUniq(val); } uint64_t readFpcr() { return xc->readFpcr(); } - void setFpcr(uint64_t val) { return xc->setFpcr(val); } + void setFpcr(uint64_t val) { xc->setFpcr(val); } #ifdef FULL_SYSTEM uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } @@ -300,7 +335,7 @@ class SimpleCPU : public BaseCPU int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { return xc->ev5_trap(fault); } + void ev5_trap(Fault fault) { xc->ev5_trap(fault); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From b4405682d9f0d7bd01ff461a7e457f8dbbfff1a0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 21 May 2004 13:03:17 -0400 Subject: Change the namespace Statistics to Stats --HG-- extra : convert_revision : 3084b292bbe2e8a392af8e99a31763ca0b0a9467 --- arch/alpha/alpha_memory.hh | 32 ++++++++++++++++---------------- arch/alpha/pseudo_inst.cc | 8 ++++---- base/hybrid_pred.cc | 4 ++-- base/hybrid_pred.hh | 32 ++++++++++++++++---------------- base/sat_counter.cc | 4 ++-- base/sat_counter.hh | 36 ++++++++++++++++++------------------ base/statistics.cc | 4 ++-- base/statistics.hh | 4 ++-- base/stats/flags.hh | 4 ++-- base/stats/mysql.cc | 4 ++-- base/stats/mysql.hh | 4 ++-- base/stats/output.hh | 4 ++-- base/stats/statdb.cc | 4 ++-- base/stats/statdb.hh | 4 ++-- base/stats/text.cc | 10 +++++----- base/stats/text.hh | 4 ++-- base/stats/types.hh | 4 ++-- base/stats/visit.cc | 4 ++-- base/stats/visit.hh | 4 ++-- cpu/base_cpu.cc | 2 +- cpu/base_cpu.hh | 2 +- cpu/exec_context.cc | 2 +- cpu/memtest/memtest.cc | 2 +- cpu/memtest/memtest.hh | 6 +++--- cpu/simple_cpu/simple_cpu.cc | 2 +- cpu/simple_cpu/simple_cpu.hh | 12 ++++++------ kern/system_events.hh | 2 +- sim/main.cc | 10 +++++----- sim/process.cc | 2 +- sim/process.hh | 2 +- sim/sim_object.cc | 2 +- sim/stat_control.cc | 26 +++++++++++++------------- sim/stat_control.hh | 4 ++-- sim/stats.hh | 4 ++-- sim/system.cc | 12 ++++++------ sim/system.hh | 10 +++++----- test/stattest.cc | 2 +- 37 files changed, 139 insertions(+), 139 deletions(-) diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 12196c44b..b5fc18255 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -80,10 +80,10 @@ class AlphaTLB : public SimObject class AlphaITB : public AlphaTLB { protected: - mutable Statistics::Scalar<> hits; - mutable Statistics::Scalar<> misses; - mutable Statistics::Scalar<> acv; - mutable Statistics::Formula accesses; + mutable Stats::Scalar<> hits; + mutable Stats::Scalar<> misses; + mutable Stats::Scalar<> acv; + mutable Stats::Formula accesses; protected: void fault(Addr pc, ExecContext *xc) const; @@ -98,18 +98,18 @@ class AlphaITB : public AlphaTLB class AlphaDTB : public AlphaTLB { protected: - mutable Statistics::Scalar<> read_hits; - mutable Statistics::Scalar<> read_misses; - mutable Statistics::Scalar<> read_acv; - mutable Statistics::Scalar<> read_accesses; - mutable Statistics::Scalar<> write_hits; - mutable Statistics::Scalar<> write_misses; - mutable Statistics::Scalar<> write_acv; - mutable Statistics::Scalar<> write_accesses; - Statistics::Formula hits; - Statistics::Formula misses; - Statistics::Formula acv; - Statistics::Formula accesses; + mutable Stats::Scalar<> read_hits; + mutable Stats::Scalar<> read_misses; + mutable Stats::Scalar<> read_acv; + mutable Stats::Scalar<> read_accesses; + mutable Stats::Scalar<> write_hits; + mutable Stats::Scalar<> write_misses; + mutable Stats::Scalar<> write_acv; + mutable Stats::Scalar<> write_accesses; + Stats::Formula hits; + Stats::Formula misses; + Stats::Formula acv; + Stats::Formula accesses; protected: void fault(Addr pc, uint64_t flags, ExecContext *xc) const; diff --git a/arch/alpha/pseudo_inst.cc b/arch/alpha/pseudo_inst.cc index 0a5c5b006..12dacebd9 100644 --- a/arch/alpha/pseudo_inst.cc +++ b/arch/alpha/pseudo_inst.cc @@ -37,7 +37,7 @@ #include "sim/stats.hh" using namespace std; -using namespace Statistics; +using namespace Stats; namespace AlphaPseudo { @@ -98,7 +98,7 @@ namespace AlphaPseudo Tick when = curTick + NS2Ticks(delay); Tick repeat = NS2Ticks(period); - using namespace Statistics; + using namespace Stats; SetupEvent(Reset, when, repeat); } @@ -114,7 +114,7 @@ namespace AlphaPseudo Tick when = curTick + NS2Ticks(delay); Tick repeat = NS2Ticks(period); - using namespace Statistics; + using namespace Stats; SetupEvent(Dump, when, repeat); } @@ -130,7 +130,7 @@ namespace AlphaPseudo Tick when = curTick + NS2Ticks(delay); Tick repeat = NS2Ticks(period); - using namespace Statistics; + using namespace Stats; SetupEvent(Dump|Reset, when, repeat); } diff --git a/base/hybrid_pred.cc b/base/hybrid_pred.cc index 12bab975b..41cf88675 100644 --- a/base/hybrid_pred.cc +++ b/base/hybrid_pred.cc @@ -63,7 +63,7 @@ HybridPredictor::HybridPredictor(const char *_p_name, const char *_z_name, void HybridPredictor::regStats() { - using namespace Statistics; + using namespace Stats; string p_name; stringstream description; @@ -148,7 +148,7 @@ void HybridPredictor::regStats() void HybridPredictor::regFormulas() { - using namespace Statistics; + using namespace Stats; string p_name; stringstream description; diff --git a/base/hybrid_pred.hh b/base/hybrid_pred.hh index 9063f3084..a76977ae2 100644 --- a/base/hybrid_pred.hh +++ b/base/hybrid_pred.hh @@ -59,22 +59,22 @@ class HybridPredictor : public GenericPredictor // // Stats // - Statistics::Scalar<> pred_one; //num_one_preds - Statistics::Scalar<> pred_zero; //num_zero_preds - Statistics::Scalar<> correct_pred_one; //num_one_correct - Statistics::Scalar<> correct_pred_zero; //num_zero_correct - Statistics::Scalar<> record_one; //num_one_updates - Statistics::Scalar<> record_zero; //num_zero_updates - - Statistics::Formula total_preds; - Statistics::Formula frac_preds_zero; - Statistics::Formula frac_preds_one; - Statistics::Formula total_correct; - Statistics::Formula total_accuracy; - Statistics::Formula zero_accuracy; - Statistics::Formula one_accuracy; - Statistics::Formula zero_coverage; - Statistics::Formula one_coverage; + Stats::Scalar<> pred_one; //num_one_preds + Stats::Scalar<> pred_zero; //num_zero_preds + Stats::Scalar<> correct_pred_one; //num_one_correct + Stats::Scalar<> correct_pred_zero; //num_zero_correct + Stats::Scalar<> record_one; //num_one_updates + Stats::Scalar<> record_zero; //num_zero_updates + + Stats::Formula total_preds; + Stats::Formula frac_preds_zero; + Stats::Formula frac_preds_one; + Stats::Formula total_correct; + Stats::Formula total_accuracy; + Stats::Formula zero_accuracy; + Stats::Formula one_accuracy; + Stats::Formula zero_coverage; + Stats::Formula one_coverage; public: HybridPredictor(const char *_p_name, const char *_z_name, diff --git a/base/sat_counter.cc b/base/sat_counter.cc index a8367d8a0..09c8881a5 100644 --- a/base/sat_counter.cc +++ b/base/sat_counter.cc @@ -69,7 +69,7 @@ SaturatingCounterPred::SaturatingCounterPred(string p_name, void SaturatingCounterPred::regStats() { - using namespace Statistics; + using namespace Stats; stringstream name, description; // @@ -138,7 +138,7 @@ void SaturatingCounterPred::regStats() void SaturatingCounterPred::regFormulas() { - using namespace Statistics; + using namespace Stats; stringstream name, description; // diff --git a/base/sat_counter.hh b/base/sat_counter.hh index a5d9c7e8a..68addbb33 100644 --- a/base/sat_counter.hh +++ b/base/sat_counter.hh @@ -61,24 +61,24 @@ class SaturatingCounterPred : public GenericPredictor unsigned *table; // Statistics - Statistics::Scalar<> predicted_one; // Total predictions of one, preds_one - Statistics::Scalar<> predicted_zero; // Total predictions of zero, preds_zero - Statistics::Scalar<> correct_pred_one; // Total correct predictions of one, correct_one - Statistics::Scalar<> correct_pred_zero; // Total correct predictions of zero, correct_zero - - Statistics::Scalar<> record_zero; //updates_zero - Statistics::Scalar<> record_one; //updates_one - - Statistics::Formula preds_total; - Statistics::Formula pred_frac_zero; - Statistics::Formula pred_frac_one; - Statistics::Formula correct_total; - Statistics::Formula updates_total; - Statistics::Formula pred_rate; - Statistics::Formula frac_correct_zero; - Statistics::Formula frac_correct_one; - Statistics::Formula coverage_zero; - Statistics::Formula coverage_one; + Stats::Scalar<> predicted_one; // Total predictions of one, preds_one + Stats::Scalar<> predicted_zero; // Total predictions of zero, preds_zero + Stats::Scalar<> correct_pred_one; // Total correct predictions of one, correct_one + Stats::Scalar<> correct_pred_zero; // Total correct predictions of zero, correct_zero + + Stats::Scalar<> record_zero; //updates_zero + Stats::Scalar<> record_one; //updates_one + + Stats::Formula preds_total; + Stats::Formula pred_frac_zero; + Stats::Formula pred_frac_one; + Stats::Formula correct_total; + Stats::Formula updates_total; + Stats::Formula pred_rate; + Stats::Formula frac_correct_zero; + Stats::Formula frac_correct_one; + Stats::Formula coverage_zero; + Stats::Formula coverage_one; private: bool pred_one(unsigned &counter) { return counter > thresh; } diff --git a/base/statistics.cc b/base/statistics.cc index 1a44cd342..78012bff7 100644 --- a/base/statistics.cc +++ b/base/statistics.cc @@ -46,7 +46,7 @@ using namespace std; -namespace Statistics { +namespace Stats { StatData * DataAccess::find() const @@ -346,4 +346,4 @@ registerResetCallback(Callback *cb) resetQueue.add(cb); } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/statistics.hh b/base/statistics.hh index ee09cc622..bd1698ae7 100644 --- a/base/statistics.hh +++ b/base/statistics.hh @@ -70,7 +70,7 @@ class Callback; extern Tick curTick; /* A namespace for all of the Statistics */ -namespace Statistics { +namespace Stats { /* Contains the statistic implementation details */ ////////////////////////////////////////////////////////////////////// @@ -2897,6 +2897,6 @@ sum(Temp val) return NodePtr(new SumNode >(val)); } -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATISTICS_HH__ diff --git a/base/stats/flags.hh b/base/stats/flags.hh index 2303de172..b86f87d25 100644 --- a/base/stats/flags.hh +++ b/base/stats/flags.hh @@ -28,7 +28,7 @@ #ifndef __BASE_STATS_FLAGS_HH__ #define __BASE_STATS_FLAGS_HH__ -namespace Statistics { +namespace Stats { /** * Define the storage for format flags. @@ -68,6 +68,6 @@ enum DisplayMode extern DisplayMode DefaultMode; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_FLAGS_HH__ diff --git a/base/stats/mysql.cc b/base/stats/mysql.cc index 676bc555c..c16332d1b 100644 --- a/base/stats/mysql.cc +++ b/base/stats/mysql.cc @@ -44,7 +44,7 @@ using namespace std; -namespace Statistics { +namespace Stats { struct MySqlData { @@ -841,4 +841,4 @@ MySql::visit(const FormulaData &data) output(data); } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/stats/mysql.hh b/base/stats/mysql.hh index 4ff474752..dd88f5724 100644 --- a/base/stats/mysql.hh +++ b/base/stats/mysql.hh @@ -34,7 +34,7 @@ #include "base/stats/output.hh" namespace MySQL { class Connection; } -namespace Statistics { +namespace Stats { class DistDataData; class MySqlData; @@ -144,6 +144,6 @@ class MySql : public Output void configure(const FormulaData &data); }; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_MYSQL_HH__ diff --git a/base/stats/output.hh b/base/stats/output.hh index 9f1fbf415..186d7bab1 100644 --- a/base/stats/output.hh +++ b/base/stats/output.hh @@ -33,7 +33,7 @@ #include "base/stats/visit.hh" -namespace Statistics { +namespace Stats { struct Output : public Visit { @@ -42,6 +42,6 @@ struct Output : public Visit virtual bool valid() const = 0; }; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_OUTPUT_HH__ diff --git a/base/stats/statdb.cc b/base/stats/statdb.cc index f54272a50..cd5a095c0 100644 --- a/base/stats/statdb.cc +++ b/base/stats/statdb.cc @@ -34,7 +34,7 @@ using namespace std; -namespace Statistics { +namespace Stats { namespace Database { StatData * @@ -86,4 +86,4 @@ TheDatabase &db() } /* namespace Database */ } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/stats/statdb.hh b/base/stats/statdb.hh index fb672e1dc..6935a9aa0 100644 --- a/base/stats/statdb.hh +++ b/base/stats/statdb.hh @@ -36,7 +36,7 @@ class Python; -namespace Statistics { +namespace Stats { class MainBin; class StatData; @@ -69,6 +69,6 @@ void regPrint(void *stat); inline std::string name() { return "Statistics Database"; } /* namespace Database */ } -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_STATDB_HH__ diff --git a/base/stats/text.cc b/base/stats/text.cc index 79a91e661..511dbe638 100644 --- a/base/stats/text.cc +++ b/base/stats/text.cc @@ -60,7 +60,7 @@ __nan() } #endif -namespace Statistics { +namespace Stats { Text::Text() : mystream(false), stream(NULL), compat(false), descriptions(false) @@ -282,14 +282,14 @@ VectorPrint::operator()(std::ostream &stream) const print(stream); } - if (flags & ::Statistics::total) { + if (flags & ::Stats::total) { print.name = base + "total"; print.desc = desc; print.value = total; print(stream); } } else { - if (flags & ::Statistics::total) { + if (flags & ::Stats::total) { print.value = total; print(stream); } @@ -640,7 +640,7 @@ Text::visit(const Vector2dData &data) print(*stream); } - if ((data.flags & ::Statistics::total) && (data.x > 1)) { + if ((data.flags & ::Stats::total) && (data.x > 1)) { print.name = data.name; print.desc = data.desc; print.vec = tot_vec; @@ -728,4 +728,4 @@ Text::visit(const FormulaData &data) visit((const VectorData &)data); } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/stats/text.hh b/base/stats/text.hh index 89bddf0cb..88e32ff0a 100644 --- a/base/stats/text.hh +++ b/base/stats/text.hh @@ -34,7 +34,7 @@ #include "base/stats/output.hh" -namespace Statistics { +namespace Stats { class Text : public Output { @@ -72,6 +72,6 @@ class Text : public Output virtual void output(); }; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_TEXT_HH__ diff --git a/base/stats/types.hh b/base/stats/types.hh index 4451c4e6e..dcfbd5fa9 100644 --- a/base/stats/types.hh +++ b/base/stats/types.hh @@ -32,7 +32,7 @@ #include #include -namespace Statistics { +namespace Stats { /** All counters are of 64-bit values. */ typedef double Counter; @@ -44,6 +44,6 @@ typedef double Result; /** vector of results. */ typedef std::vector VResult; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_TYPES_HH__ diff --git a/base/stats/visit.cc b/base/stats/visit.cc index fec11b262..88cd466b4 100644 --- a/base/stats/visit.cc +++ b/base/stats/visit.cc @@ -28,7 +28,7 @@ #include "base/stats/visit.hh" -namespace Statistics { +namespace Stats { namespace Detail { Visit::Visit() @@ -38,4 +38,4 @@ Visit::~Visit() {} /* namespace Detail */ } -/* namespace Statistics */ } +/* namespace Stats */ } diff --git a/base/stats/visit.hh b/base/stats/visit.hh index a03842c52..3a46bb9ef 100644 --- a/base/stats/visit.hh +++ b/base/stats/visit.hh @@ -34,7 +34,7 @@ #include "base/time.hh" #include "sim/host.hh" -namespace Statistics { +namespace Stats { class StatData; class ScalarData; @@ -58,6 +58,6 @@ struct Visit virtual void visit(const FormulaData &data) = 0; }; -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __BASE_STATS_VISIT_HH__ diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc index 624023f0a..702a9afe8 100644 --- a/cpu/base_cpu.cc +++ b/cpu/base_cpu.cc @@ -130,7 +130,7 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, void BaseCPU::regStats() { - using namespace Statistics; + using namespace Stats; numCycles .name(name() + ".numCycles") diff --git a/cpu/base_cpu.hh b/cpu/base_cpu.hh index c4826cf15..9c4026784 100644 --- a/cpu/base_cpu.hh +++ b/cpu/base_cpu.hh @@ -167,7 +167,7 @@ class BaseCPU : public SimObject public: // Number of CPU cycles simulated - Statistics::Scalar<> numCycles; + Stats::Scalar<> numCycles; }; #endif // __BASE_CPU_HH__ diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index a89cf4bb5..7f7719bf0 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -128,7 +128,7 @@ ExecContext::serialize(ostream &os) SERIALIZE_SCALAR(ctx); } if (system->bin) { - Statistics::MainBin *cur = Statistics::MainBin::curBin(); + Stats::MainBin *cur = Stats::MainBin::curBin(); string bin_name = cur->name(); SERIALIZE_SCALAR(bin_name); } diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 5d608976d..1d745724f 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -186,7 +186,7 @@ MemTest::completeRequest(MemReqPtr &req, uint8_t *data) void MemTest::regStats() { - using namespace Statistics; + using namespace Stats; numReadsStat diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index f2409d54c..4bde5c066 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -111,9 +111,9 @@ class MemTest : public BaseCPU Tick noResponseCycles; uint64_t numReads; - Statistics::Scalar<> numReadsStat; - Statistics::Scalar<> numWritesStat; - Statistics::Scalar<> numCopiesStat; + Stats::Scalar<> numReadsStat; + Stats::Scalar<> numWritesStat; + Stats::Scalar<> numCopiesStat; // called by MemCompleteEvent::process() void completeRequest(MemReqPtr &req, uint8_t *data); diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 617c91e68..765507345 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -254,7 +254,7 @@ SimpleCPU::haltContext(int thread_num) void SimpleCPU::regStats() { - using namespace Statistics; + using namespace Stats; BaseCPU::regStats(); diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index 0c7204fcd..1c6b18d03 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -210,7 +210,7 @@ class SimpleCPU : public BaseCPU // number of simulated instructions Counter numInst; Counter startNumInst; - Statistics::Scalar<> numInsts; + Stats::Scalar<> numInsts; virtual Counter totalInstructions() const { @@ -218,22 +218,22 @@ class SimpleCPU : public BaseCPU } // number of simulated memory references - Statistics::Scalar<> numMemRefs; + Stats::Scalar<> numMemRefs; // number of simulated loads Counter numLoad; Counter startNumLoad; // number of idle cycles - Statistics::Average<> notIdleFraction; - Statistics::Formula idleFraction; + Stats::Average<> notIdleFraction; + Stats::Formula idleFraction; // number of cycles stalled for I-cache misses - Statistics::Scalar<> icacheStallCycles; + Stats::Scalar<> icacheStallCycles; Counter lastIcacheStall; // number of cycles stalled for D-cache misses - Statistics::Scalar<> dcacheStallCycles; + Stats::Scalar<> dcacheStallCycles; Counter lastDcacheStall; void processCacheCompletion(); diff --git a/kern/system_events.hh b/kern/system_events.hh index fdf2a06c9..dba3f326c 100644 --- a/kern/system_events.hh +++ b/kern/system_events.hh @@ -50,7 +50,7 @@ class FnEvent : public PCEvent private: std::string _name; - Statistics::MainBin *myBin; + Stats::MainBin *myBin; }; #endif // __SYSTEM_EVENTS_HH__ diff --git a/sim/main.cc b/sim/main.cc index 8861f3ef0..032a05668 100644 --- a/sim/main.cc +++ b/sim/main.cc @@ -236,7 +236,7 @@ main(int argc, char **argv) sayHello(cerr); // Initialize statistics database - Statistics::InitSimStats(); + Stats::InitSimStats(); vector cppArgs; @@ -390,10 +390,10 @@ main(int argc, char **argv) #endif // Check to make sure that the stats package is properly initialized - Statistics::check(); + Stats::check(); // Reset to put the stats in a consistent state. - Statistics::reset(); + Stats::reset(); // Nothing to simulate if we don't have at least one CPU somewhere. if (BaseCPU::numSimulatedCPUs() == 0) { @@ -418,14 +418,14 @@ main(int argc, char **argv) if (async_dump) { async_dump = false; - using namespace Statistics; + using namespace Stats; SetupEvent(Dump, curTick); } if (async_dumpreset) { async_dumpreset = false; - using namespace Statistics; + using namespace Stats; SetupEvent(Dump | Reset, curTick); } diff --git a/sim/process.cc b/sim/process.cc index c6b497343..65cb8409f 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -95,7 +95,7 @@ Process::Process(const string &name, void Process::regStats() { - using namespace Statistics; + using namespace Stats; num_syscalls .name(name() + ".PROG:num_syscalls") diff --git a/sim/process.hh b/sim/process.hh index b23302b8f..d235f0ef1 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -98,7 +98,7 @@ class Process : public SimObject std::string prog_fname; // file name Addr prog_entry; // entry point (initial PC) - Statistics::Scalar<> num_syscalls; // number of syscalls executed + Stats::Scalar<> num_syscalls; // number of syscalls executed protected: diff --git a/sim/sim_object.cc b/sim/sim_object.cc index 9626c54ea..7f756858c 100644 --- a/sim/sim_object.cc +++ b/sim/sim_object.cc @@ -120,7 +120,7 @@ SimObject::regAllStats() (*i)->regFormulas(); } - Statistics::registerResetCallback(&StatResetCB); + Stats::registerResetCallback(&StatResetCB); } // diff --git a/sim/stat_control.cc b/sim/stat_control.cc index c7d2fdd5b..28ee348b5 100644 --- a/sim/stat_control.cc +++ b/sim/stat_control.cc @@ -47,17 +47,17 @@ using namespace std; -Statistics::Formula hostInstRate; -Statistics::Formula hostTickRate; -Statistics::Value hostMemory; -Statistics::Value hostSeconds; +Stats::Formula hostInstRate; +Stats::Formula hostTickRate; +Stats::Value hostMemory; +Stats::Value hostSeconds; -Statistics::Value simTicks; -Statistics::Value simInsts; -Statistics::Value simFreq; -Statistics::Formula simSeconds; +Stats::Value simTicks; +Stats::Value simInsts; +Stats::Value simFreq; +Stats::Formula simSeconds; -namespace Statistics { +namespace Stats { Time statTime(true); Tick startTick; @@ -173,10 +173,10 @@ StatEvent::description() void StatEvent::process() { - if (flags & Statistics::Dump) + if (flags & Stats::Dump) DumpNow(); - if (flags & Statistics::Reset) + if (flags & Stats::Reset) reset(); if (repeat) @@ -205,11 +205,11 @@ SetupEvent(int flags, Tick when, Tick repeat) new StatEvent(flags, when, repeat); } -/* namespace Statistics */ } +/* namespace Stats */ } extern "C" void debugDumpStats() { - Statistics::DumpNow(); + Stats::DumpNow(); } diff --git a/sim/stat_control.hh b/sim/stat_control.hh index 9a5e269e1..56170dc77 100644 --- a/sim/stat_control.hh +++ b/sim/stat_control.hh @@ -32,7 +32,7 @@ #include #include -namespace Statistics { +namespace Stats { enum { Reset = 0x1, @@ -47,6 +47,6 @@ void SetupEvent(int flags, Tick when, Tick repeat = 0); void InitSimStats(); -/* namespace Statistics */ } +/* namespace Stats */ } #endif // __SIM_STAT_CONTROL_HH__ diff --git a/sim/stats.hh b/sim/stats.hh index c5e791cfb..218036eb6 100644 --- a/sim/stats.hh +++ b/sim/stats.hh @@ -31,7 +31,7 @@ #include "base/statistics.hh" -extern Statistics::Formula simSeconds; -extern Statistics::Value simTicks; +extern Stats::Formula simSeconds; +extern Stats::Value simTicks; #endif // __SIM_SIM_STATS_HH__ diff --git a/sim/system.cc b/sim/system.cc index 791a092ac..619593abd 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -55,19 +55,19 @@ System::System(const std::string _name, // add self to global system list systemList.push_back(this); if (bin == true) { - Kernel = new Statistics::MainBin("non TCPIP Kernel stats"); + Kernel = new Stats::MainBin("non TCPIP Kernel stats"); Kernel->activate(); - User = new Statistics::MainBin("User stats"); + User = new Stats::MainBin("User stats"); int end = binned_fns.size(); assert(!(end & 1)); - Statistics::MainBin *Bin; + Stats::MainBin *Bin; fnEvents.resize(end>>1); for (int i = 0; i < end; i +=2) { - Bin = new Statistics::MainBin(binned_fns[i]); + Bin = new Stats::MainBin(binned_fns[i]); fnBins.insert(make_pair(binned_fns[i], Bin)); fnEvents[(i>>1)] = new FnEvent(&pcEventQueue, binned_fns[i], this); @@ -178,10 +178,10 @@ System::dumpState(ExecContext *xc) const } } -Statistics::MainBin * +Stats::MainBin * System::getBin(const std::string &name) { - std::map::const_iterator i; + std::map::const_iterator i; i = fnBins.find(name); if (i == fnBins.end()) panic("trying to getBin %s that is not on system map!", name); diff --git a/sim/system.hh b/sim/system.hh index 564579fe4..b83945884 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -50,18 +50,18 @@ class System : public SimObject { // lisa's binning stuff private: - std::map fnBins; + std::map fnBins; std::map swCtxMap; protected: std::vector fnEvents; public: - Statistics::Scalar<> fnCalls; - Statistics::MainBin *Kernel; - Statistics::MainBin *User; + Stats::Scalar<> fnCalls; + Stats::MainBin *Kernel; + Stats::MainBin *User; - Statistics::MainBin * getBin(const std::string &name); + Stats::MainBin * getBin(const std::string &name); bool findCaller(std::string, std::string) const; SWContext *findContext(Addr pcb); diff --git a/test/stattest.cc b/test/stattest.cc index 9b7ba9857..1a035859a 100644 --- a/test/stattest.cc +++ b/test/stattest.cc @@ -41,7 +41,7 @@ #include "sim/host.hh" using namespace std; -using namespace Statistics; +using namespace Stats; Tick curTick = 0; Tick ticksPerSecond = ULL(2000000000); -- cgit v1.2.3 From fee1e1ec0a9c1122f3c42fdef9482c64389949fc Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 21 May 2004 13:57:44 -0400 Subject: Add support for event tracking. Esentially this puts a sequence of events into the database for a given run. base/stats/mysql.cc: base/stats/mysql.hh: reorganize mysql stat stuff so that other stuff can use the same database connection base/traceflags.py: Trace flag to print out events --HG-- extra : convert_revision : 4d502532ed0ba40b42baefee46b2c99defcc620c --- base/stats/events.cc | 105 +++++++++++++++++++++++++ base/stats/events.hh | 63 +++++++++++++++ base/stats/mysql.cc | 199 ++++++++++++++++-------------------------------- base/stats/mysql.hh | 44 ++++++----- base/stats/mysql_run.hh | 63 +++++++++++++++ base/traceflags.py | 1 + 6 files changed, 320 insertions(+), 155 deletions(-) create mode 100644 base/stats/events.cc create mode 100644 base/stats/events.hh create mode 100644 base/stats/mysql_run.hh diff --git a/base/stats/events.cc b/base/stats/events.cc new file mode 100644 index 000000000..3a858611f --- /dev/null +++ b/base/stats/events.cc @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2004 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. + */ + +#ifdef USE_MYSQL +#include "base/cprintf.hh" +#include "base/misc.hh" +#include "base/mysql.hh" +#include "base/stats/events.hh" +#include "base/stats/mysql.hh" +#include "base/stats/mysql_run.hh" +#include "base/str.hh" +#endif + +#include "sim/host.hh" +#include "sim/universe.hh" + +using namespace std; + +namespace Stats { + +Tick EventStart = ULL(0xffffffffffffffff); + +#ifdef USE_MYSQL +typedef map event_map_t; +event_map_t event_map; + +void +__event(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); + uint32_t event; + if (i == event_map.end()) { + mysql.query( + csprintf("SELECT en_id " + "from event_names " + "where en_name=\"%s\"", + stat)); + + MySQL::Result result = mysql.store_result(); + if (result) { + assert(result.num_fields() == 1); + MySQL::Row row = result.fetch_row(); + if (!row) + panic("could not get a run\n%s\n", mysql.error); + 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; + } + + mysql.query( + csprintf("INSERT INTO " + "events(ev_event, ev_run, ev_tick)" + "values(%d, %d, %d)", + event, run, curTick)); + + if (mysql.error) + panic("could not get a run\n%s\n", mysql.error); + +} +#endif + +/* namespace Stats */ } diff --git a/base/stats/events.hh b/base/stats/events.hh new file mode 100644 index 000000000..49c060645 --- /dev/null +++ b/base/stats/events.hh @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 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. + */ + +#ifndef __BASE_STATS_EVENTS_HH__ +#define __BASE_STATS_EVENTS_HH__ + +#include + +#include "base/trace.hh" + +namespace Stats { + +extern Tick EventStart; + +#ifdef USE_MYSQL +void __event(const std::string &stat); +bool MySqlConnected(); +#endif + +inline void +recordEvent(const std::string &stat) +{ + if (EventStart > curTick) + return; + + DPRINTF(StatEvents, "Statistics Event: %s\n", stat); + +#ifdef USE_MYSQL + if (!MySqlConnected()) + return; + + __event(stat); +#endif +} + +/* namespace Stats */ } + +#endif // __BASE_STATS_EVENTS_HH__ diff --git a/base/stats/mysql.cc b/base/stats/mysql.cc index c16332d1b..05808c211 100644 --- a/base/stats/mysql.cc +++ b/base/stats/mysql.cc @@ -37,6 +37,7 @@ #include "base/statistics.hh" #include "base/stats/flags.hh" #include "base/stats/mysql.hh" +#include "base/stats/mysql_run.hh" #include "base/stats/statdb.hh" #include "base/stats/types.hh" #include "base/str.hh" @@ -46,17 +47,33 @@ using namespace std; namespace Stats { -struct MySqlData +MySqlRun MySqlDB; + +bool +MySqlConnected() { - map idmap; - MySQL::Connection conn; -}; + return MySqlDB.connected(); +} -int -SetupRun(MySqlData *data, const string &name, const string &user, - const string &project) +void +MySqlRun::connect(const string &host, const string &user, const string &passwd, + const string &db, const string &name, const string &project) +{ + if (connected()) + panic("can only get one database connection at this time!"); + + mysql.connect(host, user, passwd, db); + if (mysql.error) + panic("could not connect to database server\n%s\n", mysql.error); + + remove(name); + cleanup(); + setup(name, user, project); +} + +void +MySqlRun::setup(const string &name, const string &user, const string &project) { - MySQL::Connection &mysql = data->conn; assert(mysql.connected()); stringstream insert; @@ -71,13 +88,12 @@ SetupRun(MySqlData *data, const string &name, const string &user, if (mysql.error) panic("could not get a run\n%s\n", mysql.error); - return mysql.insert_id(); + run_id = mysql.insert_id(); } void -DeleteRun(MySqlData *data, const string &name) +MySqlRun::remove(const string &name) { - MySQL::Connection &mysql = data->conn; assert(mysql.connected()); stringstream sql; ccprintf(sql, "DELETE FROM runs WHERE rn_name=\"%s\"", name); @@ -85,9 +101,8 @@ DeleteRun(MySqlData *data, const string &name) } void -Cleanup(MySqlData *data) +MySqlRun::cleanup() { - MySQL::Connection &mysql = data->conn; assert(mysql.connected()); mysql.query("DELETE data " @@ -142,9 +157,9 @@ SetupStat::init() } unsigned -SetupStat::operator()(MySqlData *data) +SetupStat::setup() { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); stringstream insert; ccprintf(insert, @@ -245,9 +260,9 @@ SetupStat::operator()(MySqlData *data) } unsigned -SetupBin(MySqlData *data, const string &bin) +SetupBin(const string &bin) { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); assert(mysql.connected()); using namespace MySQL; @@ -292,8 +307,9 @@ void InsertData::flush() { if (size) { - assert(mysql && mysql->connected()); - mysql->query(query); + MySQL::Connection &mysql = MySqlDB.conn(); + assert(mysql.connected()); + mysql.query(query); } query[0] = '\0'; @@ -319,7 +335,8 @@ InsertData::insert() first = false; size += sprintf(query + size, "(%u,%d,%d,%u,%llu,%u,\"%f\")", - stat, x, y, run, (unsigned long long)sample, bin, data); + stat, x, y, MySqlDB.run(), (unsigned long long)sample, + bin, data); } struct InsertSubData @@ -330,13 +347,13 @@ struct InsertSubData string name; string descr; - void operator()(MySqlData *data); + void setup(); }; void -InsertSubData::operator()(MySqlData *data) +InsertSubData::setup() { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); assert(mysql.connected()); stringstream insert; ccprintf(insert, @@ -348,10 +365,9 @@ InsertSubData::operator()(MySqlData *data) } void -InsertFormula(MySqlData *data, uint16_t stat, uint16_t run, - const string &formula) +InsertFormula(uint16_t stat, const string &formula) { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); assert(mysql.connected()); stringstream insert_formula; ccprintf(insert_formula, @@ -363,15 +379,15 @@ InsertFormula(MySqlData *data, uint16_t stat, uint16_t run, stringstream insert_ref; ccprintf(insert_ref, "INSERT INTO formula_ref(fr_stat,fr_run) values(%d, %d)", - stat, run); + stat, MySqlDB.run()); mysql.query(insert_ref); } void -UpdatePrereq(MySqlData *data, uint16_t stat, uint16_t prereq) +UpdatePrereq(uint16_t stat, uint16_t prereq) { - MySQL::Connection &mysql = data->conn; + MySQL::Connection &mysql = MySqlDB.conn(); assert(mysql.connected()); stringstream update; ccprintf(update, "UPDATE stats SET st_prereq=%d WHERE st_id=%d", @@ -379,98 +395,6 @@ UpdatePrereq(MySqlData *data, uint16_t stat, uint16_t prereq) mysql.query(update); } -#if 0 -class InsertData -{ - private: - MySQL::Connection &mysql; - MySQL::Statement stmt; - - public: - InsertData(MySqlData *data) - : mysql(data->conn) - { - stmt.prepare("INSERT INTO " - "data(dt_stat,dt_x,dt_y,dt_run,dt_sample,dt_bin,dt_data) " - "values(?,?,?,?,?,?,?)"); - assert(stmt.count() == 7 && "param count invalid"); - - stmt[0].buffer = stat; - stmt[1].buffer = x; - stmt[2].buffer = y; - stmt[3].buffer = run; - stmt[4].buffer = sample; - stmt[5].buffer = bin; - stmt[6].buffer = data; - - stmt.bind(bind); - if (stmt.error) - panic("bind param failed\n%s\n", stmt.error); - } - - public: - uint64_t sample; - uint64_t data; - uint16_t stat; - uint16_t bin; - int16_t x; - int16_t y; - - void operator()(MySQL::Connection &mysql) - { - assert(mysql.connected()) - stmt(); - } -}; -#endif - - -MySql::MySql() - : mysql(NULL), configured(false) -{ -} - -MySql::~MySql() -{ - if (mysql) - delete mysql; -} - -void -MySql::insert(int sim_id, int db_id) -{ - mysql->idmap.insert(make_pair(sim_id, db_id)); -} - -int -MySql::find(int sim_id) -{ - map::const_iterator i = mysql->idmap.find(sim_id); - assert(i != mysql->idmap.end()); - return (*i).second; -} - -bool -MySql::valid() const -{ - return mysql && mysql->conn.connected(); -} - -void -MySql::connect(const string &host, const string &user, const string &passwd, - const string &db, const string &name, const string &project) -{ - mysql = new MySqlData; - newdata.mysql = &mysql->conn; - mysql->conn.connect(host, user, passwd, db); - if (mysql->conn.error) - panic("could not connect to database server\n%s\n", mysql->conn.error); - - DeleteRun(mysql, name); - Cleanup(mysql); - run_id = SetupRun(mysql, name, user, project); -} - void MySql::configure() { @@ -489,7 +413,7 @@ MySql::configure() uint16_t prereq_id = find(data->prereq->id); assert(stat_id && prereq_id); - UpdatePrereq(mysql, stat_id, prereq_id); + UpdatePrereq(stat_id, prereq_id); } } @@ -517,14 +441,14 @@ void MySql::configure(const ScalarData &data) { configure(data, "SCALAR"); - insert(data.id, stat(mysql)); + insert(data.id, stat.setup()); } void MySql::configure(const VectorData &data) { configure(data, "VECTOR"); - uint16_t statid = stat(mysql); + uint16_t statid = stat.setup(); if (!data.subnames.empty()) { InsertSubData subdata; @@ -536,7 +460,7 @@ MySql::configure(const VectorData &data) subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) - subdata(mysql); + subdata.setup(); } } @@ -553,7 +477,7 @@ MySql::configure(const DistData &data) stat.max = data.data.max; stat.bktsize = data.data.bucket_size; } - insert(data.id, stat(mysql)); + insert(data.id, stat.setup()); } void @@ -568,7 +492,7 @@ MySql::configure(const VectorDistData &data) stat.bktsize = data.data[0].bucket_size; } - uint16_t statid = stat(mysql); + uint16_t statid = stat.setup(); if (!data.subnames.empty()) { InsertSubData subdata; @@ -579,7 +503,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(mysql); + subdata.setup(); } } @@ -590,7 +514,7 @@ void MySql::configure(const Vector2dData &data) { configure(data, "VECTOR2D"); - uint16_t statid = stat(mysql); + uint16_t statid = stat.setup(); if (!data.subnames.empty()) { InsertSubData subdata; @@ -601,7 +525,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(mysql); + subdata.setup(); } } @@ -614,7 +538,7 @@ MySql::configure(const Vector2dData &data) subdata.y = i; subdata.name = data.y_subnames[i]; if (!subdata.name.empty()) - subdata(mysql); + subdata.setup(); } } @@ -625,20 +549,26 @@ void MySql::configure(const FormulaData &data) { configure(data, "FORMULA"); - insert(data.id, stat(mysql)); + insert(data.id, stat.setup()); } void MySql::output(const string &bin) { // set up new bin in database if there is a bin name - newdata.bin = bin.empty() ? 0 : SetupBin(mysql, bin); + newdata.bin = bin.empty() ? 0 : SetupBin(bin); Database::stat_list_t::const_iterator i, end = Database::stats().end(); for (i = Database::stats().begin(); i != end; ++i) (*i)->visit(*this); } +bool +MySql::valid() const +{ + return MySqlDB.connected(); +} + void MySql::output() { @@ -649,7 +579,6 @@ MySql::output() configure(); // store sample # - newdata.run = run_id; newdata.sample = curTick; if (bins().empty()) { @@ -781,7 +710,7 @@ MySql::output(const Vector2dData &data) void MySql::output(const FormulaData &data) { - InsertFormula(mysql, find(data.id), run_id, data.str()); + InsertFormula(find(data.id), data.str()); } /* diff --git a/base/stats/mysql.hh b/base/stats/mysql.hh index dd88f5724..4671b89dd 100644 --- a/base/stats/mysql.hh +++ b/base/stats/mysql.hh @@ -29,15 +29,17 @@ #ifndef __BASE_STATS_MYSQL_HH__ #define __BASE_STATS_MYSQL_HH__ +#include #include #include "base/stats/output.hh" -namespace MySQL { class Connection; } namespace Stats { class DistDataData; -class MySqlData; +class MySqlRun; +bool MySqlConnected(); +extern MySqlRun MySqlDB; struct SetupStat { @@ -58,7 +60,7 @@ struct SetupStat uint16_t size; void init(); - unsigned operator()(MySqlData *data); + unsigned setup(); }; class InsertData @@ -70,14 +72,13 @@ class InsertData static const int maxsize = 1024*1024; public: - MySQL::Connection *mysql; + MySqlRun *run; public: uint64_t sample; double data; uint16_t stat; uint16_t bin; - uint16_t run; int16_t x; int16_t y; @@ -92,25 +93,28 @@ class InsertData class MySql : public Output { protected: - std::list formulas; - MySqlData *mysql; - bool configured; - uint16_t run_id; - SetupStat stat; InsertData newdata; + std::list formulas; + bool configured; - void insert(int sim_id, int db_id); - int find(int sim_id); - + protected: + std::map idmap; + + void insert(int sim_id, int db_id) + { + using namespace std; + idmap.insert(make_pair(sim_id, db_id)); + } + + int find(int sim_id) + { + using namespace std; + map::const_iterator i = idmap.find(sim_id); + 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 &project); - // Implement Visit virtual void visit(const ScalarData &data); virtual void visit(const VectorData &data); diff --git a/base/stats/mysql_run.hh b/base/stats/mysql_run.hh new file mode 100644 index 000000000..0f8d84297 --- /dev/null +++ b/base/stats/mysql_run.hh @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004 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. + */ + +#ifndef __BASE_STATS_MYSQL_RUN_HH__ +#define __BASE_STATS_MYSQL_RUN_HH__ + +#include + +#include "base/mysql.hh" +#include "sim/host.hh" + +namespace Stats { + +struct MySqlRun +{ + private: + MySQL::Connection mysql; + uint16_t run_id; + + public: + 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); + + void setup(const std::string &name, const std::string &user, + const std::string &project); + + void remove(const std::string &name); + void cleanup(); + + MySQL::Connection &conn() { return mysql; } + uint16_t run() const { return run_id; } +}; + +/* namespace Stats */ } + +#endif // __BASE_STATS_MYSQL_RUN_HH__ diff --git a/base/traceflags.py b/base/traceflags.py index b7b7fa777..69f4e7ab8 100644 --- a/base/traceflags.py +++ b/base/traceflags.py @@ -100,6 +100,7 @@ baseFlags = [ 'Chains', 'Dispatch', 'Stats', + 'StatEvents', 'Context', 'Config', 'Sampler', -- cgit v1.2.3 From f622d74f81f6d0c451bc8437d19a38057bc0d164 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 21 May 2004 13:58:39 -0400 Subject: add a few statistics events arch/alpha/ev5.cc: Add an event for faults cpu/simple_cpu/simple_cpu.cc: add events for uncached reads/writes --HG-- extra : convert_revision : 747bdf12761e2de6ebbf54fecc9e0b71915b3a02 --- arch/alpha/ev5.cc | 17 +++++++++-------- cpu/simple_cpu/simple_cpu.cc | 7 +++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index f037a34ac..96d54c54c 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -1,15 +1,14 @@ /* $Id$ */ -#include "targetarch/alpha_memory.hh" -#ifdef DEBUG -#include "sim/debug.hh" -#endif +#include "arch/alpha/alpha_memory.hh" +#include "arch/alpha/isa_traits.hh" +#include "arch/alpha/osfpal.hh" +#include "base/kgdb.h" +#include "base/remote_gdb.hh" +#include "base/stats/events.hh" #include "cpu/exec_context.hh" +#include "sim/debug.hh" #include "sim/sim_events.hh" -#include "targetarch/isa_traits.hh" -#include "base/remote_gdb.hh" -#include "base/kgdb.h" // for ALPHA_KENTRY_IF -#include "targetarch/osfpal.hh" #ifdef FULL_SYSTEM @@ -102,6 +101,8 @@ AlphaISA::initIPRs(RegFile *regs) void ExecContext::ev5_trap(Fault fault) { + Stats::recordEvent(csprintf("Fault %s", FaultName(fault))); + assert(!misspeculating()); kernelStats.fault(fault); diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 765507345..1ade235ed 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -42,6 +42,7 @@ #include "base/pollevent.hh" #include "base/range.hh" #include "base/trace.hh" +#include "base/stats/events.hh" #include "cpu/base_cpu.hh" #include "cpu/exec_context.hh" #include "cpu/exetrace.hh" @@ -402,6 +403,9 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) } } + if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) + Stats::recordEvent("Uncached Read"); + return fault; } @@ -487,6 +491,9 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) if (res && (fault == No_Fault)) *res = memReq->result; + if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) + Stats::recordEvent("Uncached Write"); + return fault; } -- cgit v1.2.3 -- cgit v1.2.3 From 3a0dfc43d19255a04c74ef1b1017e978bc5b8796 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 23 May 2004 12:53:34 -0400 Subject: make the interaction of the stats event stuff with the database work better. base/stats/events.cc: properly connect to the database base/stats/mysql.cc: cleanup the event stuff too --HG-- extra : convert_revision : f05fd6456decc9c4f95beff5c12497439e45f886 --- base/stats/events.cc | 12 ++++++------ base/stats/mysql.cc | 10 ++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/base/stats/events.cc b/base/stats/events.cc index 3a858611f..b579981e9 100644 --- a/base/stats/events.cc +++ b/base/stats/events.cc @@ -66,11 +66,12 @@ __event(const string &stat) stat)); MySQL::Result result = mysql.store_result(); - if (result) { - assert(result.num_fields() == 1); - MySQL::Row row = result.fetch_row(); - if (!row) - panic("could not get a run\n%s\n", mysql.error); + 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 { @@ -85,7 +86,6 @@ __event(const string &stat) event = mysql.insert_id(); } - } else { event = (*i).second; } diff --git a/base/stats/mysql.cc b/base/stats/mysql.cc index 05808c211..77366beb0 100644 --- a/base/stats/mysql.cc +++ b/base/stats/mysql.cc @@ -134,6 +134,16 @@ MySqlRun::cleanup() "FROM bins " "LEFT JOIN data ON bn_id=dt_bin " "WHERE dt_bin IS NULL"); + + mysql.query("DELETE events" + "FROM events" + "LEFT JOIN runs ON ev_run=rn_id" + "WHERE rn_id IS NULL"); + + mysql.query("DELETE event_names" + "FROM event_names" + "LEFT JOIN events ON en_id=ev_event" + "WHERE ev_event IS NULL"); } void -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From a896960cbfce76a0e0c8cfb5cbdfc805ce72577b Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 27 May 2004 17:46:16 -0400 Subject: FastCPU model added. It's very similar to the SimpleCPU, just without a lot of the stats tracking. Also various changes to make the CPU model less ISA dependent, which includes moving the code that checks for interrupts up to the ISA level, moving code that zeroes the zero registers up to the ISA level, and removing opcode and ra from the regfile. arch/alpha/alpha_memory.cc: The regfile has been changed so it no longer has the opcode and ra. Instead the xc holds the actual instruction, and from there the opcode and ra can be obtained with OPCODE() and RA(). arch/alpha/ev5.cc: Moved code that once existed within simpleCPU to ev5, and templatized it. This way the CPU models can call processInterrupts and the ISA specific interrupt handling is left to the ISA's code. Also moved ISA specific zero registers from simpleCPU to here. arch/alpha/ev5.hh: Added macros for obtaining the opcode and ra from the instruction itself, as there is no longer opcode or ra in the regfile. arch/alpha/isa_desc: Added in declarations for the FastCPU model. arch/alpha/isa_traits.hh: Removed opcode and ra from the regfile. The xc now holds the actual instruction, and the opcode and ra can be obtained through it. Also added the declaration for the templated zeroRegisters() function, which will set the zero registers to 0. arch/isa_parser.py: Added in FastCPUExecContext so it will generate code for the FastCPU model as well. cpu/exec_context.cc: Added in a more generic trap function so "ev5_trap" doesn't need to be called. It currently still calls the old method, with plans for making this ISA dependent in the future. cpu/exec_context.hh: Exec context now has the instruction within it. Also added methods for exec context to read an instruction from memory, return the current instruction, and set the instruction if needed. Also has declaration for more generic trap() function. cpu/simple_cpu/simple_cpu.cc: Removed references to opcode and ra, and instead sets the xc's instruction with the fetched instruction. cpu/static_inst.hh: Added declaration for execute() using FastCPUExecContext. --HG-- extra : convert_revision : 0441ea3700ac50b733e485395d4dd4ac83666f92 --- arch/alpha/alpha_memory.cc | 4 +-- arch/alpha/ev5.cc | 67 ++++++++++++++++++++++++++++++++++++++++++++ arch/alpha/ev5.hh | 2 ++ arch/alpha/isa_desc | 37 ++++++++++++++++++++++++ arch/alpha/isa_traits.hh | 10 +++++-- arch/isa_parser.py | 4 ++- cpu/exec_context.cc | 15 ++++++++++ cpu/exec_context.hh | 24 ++++++++++++++++ cpu/simple_cpu/simple_cpu.cc | 3 +- cpu/static_inst.hh | 8 ++++++ 10 files changed, 167 insertions(+), 7 deletions(-) diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 1608cc4a4..23815bf01 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -425,8 +425,8 @@ AlphaDTB::fault(Addr vaddr, uint64_t flags, ExecContext *xc) const ipr[AlphaISA::IPR_VA] = vaddr; // set MM_STAT register flags - ipr[AlphaISA::IPR_MM_STAT] = (((xc->regs.opcode & 0x3f) << 11) - | ((xc->regs.ra & 0x1f) << 6) + ipr[AlphaISA::IPR_MM_STAT] = (((OPCODE(xc->getInst()) & 0x3f) << 11) + | ((RA(xc->getInst()) & 0x1f) << 6) | (flags & 0x3f)); // set VA_FORM register with faulting formatted address diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 9b3ac5fff..fe665abe6 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -6,6 +6,7 @@ #include "sim/debug.hh" #endif #include "cpu/exec_context.hh" +#include "cpu/fast_cpu/fast_cpu.hh" #include "sim/sim_events.hh" #include "targetarch/isa_traits.hh" #include "base/remote_gdb.hh" @@ -100,6 +101,64 @@ AlphaISA::initIPRs(RegFile *regs) } +template +void +AlphaISA::processInterrupts(XC *xc) +{ + //Check if there are any outstanding interrupts + //Handle the interrupts + int ipl = 0; + int summary = 0; + IntReg *ipr = xc->getIprPtr(); + + check_interrupts = 0; + + if (ipr[IPR_ASTRR]) + panic("asynchronous traps not implemented\n"); + + if (ipr[IPR_SIRR]) { + for (int i = INTLEVEL_SOFTWARE_MIN; + i < INTLEVEL_SOFTWARE_MAX; i++) { + if (ipr[IPR_SIRR] & (ULL(1) << i)) { + // See table 4-19 of the 21164 hardware reference + ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; + summary |= (ULL(1) << i); + } + } + } + + uint64_t interrupts = xc->intr_status(); + + if (interrupts) { + for (int i = INTLEVEL_EXTERNAL_MIN; + i < INTLEVEL_EXTERNAL_MAX; i++) { + if (interrupts & (ULL(1) << i)) { + // See table 4-19 of the 21164 hardware reference + ipl = i; + summary |= (ULL(1) << i); + } + } + } + + if (ipl && ipl > ipr[IPR_IPLR]) { + ipr[IPR_ISR] = summary; + ipr[IPR_INTID] = ipl; + xc->trap(Interrupt_Fault); + DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", + ipr[IPR_IPLR], ipl, summary); + } + +} + +template +void +AlphaISA::zeroRegisters(XC *xc) +{ + // Insure ISA semantics + xc->setIntReg(ZeroReg, 0); + xc->setFloatRegDouble(ZeroReg, 0.0); +} + void ExecContext::ev5_trap(Fault fault) { @@ -585,4 +644,12 @@ ExecContext::simPalCheck(int palFunc) return true; } +//Forward instantiation for FastCPU object +template +void AlphaISA::processInterrupts(FastCPU *xc); + +//Forward instantiation for FastCPU object +template +void AlphaISA::zeroRegisters(FastCPU *xc); + #endif // FULL_SYSTEM diff --git a/arch/alpha/ev5.hh b/arch/alpha/ev5.hh index aa3d7e226..6947ef708 100644 --- a/arch/alpha/ev5.hh +++ b/arch/alpha/ev5.hh @@ -71,6 +71,8 @@ #define MM_STAT_ACV_MASK 0x0002 #define MM_STAT_WR_MASK 0x0001 +#define OPCODE(X) (X >> 26) & 0x3f +#define RA(X) (X >> 21) & 0x1f //////////////////////////////////////////////////////////////////////// // diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc index 0d1e7138f..016040b79 100644 --- a/arch/alpha/isa_desc +++ b/arch/alpha/isa_desc @@ -22,6 +22,7 @@ let {{ #include "base/misc.hh" #include "cpu/exec_context.hh" #include "cpu/exetrace.hh" +#include "cpu/fast_cpu/fast_cpu.hh" #include "cpu/full_cpu/dyn_inst.hh" #include "cpu/simple_cpu/simple_cpu.hh" #include "cpu/static_inst.hh" @@ -312,6 +313,9 @@ declare {{ Fault execute(SimpleCPUExecContext *, Trace::InstRecord *) { return No_Fault; } + Fault execute(FastCPUExecContext *, Trace::InstRecord *) + { return No_Fault; } + Fault execute(FullCPUExecContext *, Trace::InstRecord *) { return No_Fault; } }; @@ -719,6 +723,9 @@ declare {{ Fault execute(SimpleCPUExecContext *, Trace::InstRecord *) { panic("attempt to execute eacomp"); } + Fault execute(FastCPUExecContext *, Trace::InstRecord *) + { panic("attempt to execute eacomp"); } + Fault execute(FullCPUExecContext *, Trace::InstRecord *) { panic("attempt to execute eacomp"); } }; @@ -739,6 +746,9 @@ declare {{ Fault execute(SimpleCPUExecContext *, Trace::InstRecord *) { panic("attempt to execute memacc"); } + Fault execute(FastCPUExecContext *, Trace::InstRecord *) + { panic("attempt to execute memacc"); } + Fault execute(FullCPUExecContext *, Trace::InstRecord *) { panic("attempt to execute memacc"); } }; @@ -1452,6 +1462,14 @@ declare {{ return Unimplemented_Opcode_Fault; } + Fault execute(FastCPUExecContext *xc, + Trace::InstRecord *traceData) + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } + Fault execute(FullCPUExecContext *xc, Trace::InstRecord *traceData) { @@ -1502,6 +1520,17 @@ declare {{ return No_Fault; } + Fault execute(FastCPUExecContext *xc, + Trace::InstRecord *traceData) + { + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return No_Fault; + } + Fault execute(FullCPUExecContext *xc, Trace::InstRecord *traceData) { @@ -1573,6 +1602,14 @@ declare {{ return Unimplemented_Opcode_Fault; } + Fault execute(FastCPUExecContext *xc, + Trace::InstRecord *traceData) + { + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } + Fault execute(FullCPUExecContext *xc, Trace::InstRecord *traceData) { diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 05ab89978..37ba77192 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -33,6 +33,7 @@ #include "targetarch/faults.hh" #include "base/misc.hh" +class FastCPU; class FullCPU; class Checkpoint; @@ -156,8 +157,6 @@ class AlphaISA int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers #endif // FULL_SYSTEM - // Are these architectural, or just for convenience? - uint8_t opcode, ra; // current instruction details (for intr's) void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); @@ -233,6 +232,13 @@ class AlphaISA ConfigNode *node, RegFile ®s); #endif + + /** + * Function to insure ISA semantics about 0 registers. + * @param xc The execution context. + */ + template + static void zeroRegisters(XC *xc); }; diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 0ee9e2e2d..cc42657e2 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1387,6 +1387,7 @@ class InstObjParams: self.base_class = base_class self.exec_func_declarations = ''' Fault execute(SimpleCPUExecContext *, Trace::InstRecord *); + Fault execute(FastCPUExecContext *, Trace::InstRecord *); Fault execute(FullCPUExecContext *, Trace::InstRecord *); ''' if code_block: @@ -1433,7 +1434,8 @@ class InstObjParams: error(0, 'InstObjParams::subst: undefined template "%s"' % t) if template.find('%(cpu_model)') != -1: tmp = '' - for cpu_model in ('SimpleCPUExecContext', 'FullCPUExecContext'): + for cpu_model in ('SimpleCPUExecContext', 'FastCPUExecContext', + 'FullCPUExecContext'): self.cpu_model = cpu_model tmp += self._subst(template) result.append(tmp) diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index a89cf4bb5..832a621f8 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -106,6 +106,7 @@ ExecContext::serialize(ostream &os) regs.serialize(os); // thread_num and cpu_id are deterministic from the config SERIALIZE_SCALAR(func_exe_inst); + SERIALIZE_SCALAR(inst); #ifdef FULL_SYSTEM bool ctx = false; @@ -143,6 +144,7 @@ ExecContext::unserialize(Checkpoint *cp, const std::string §ion) regs.unserialize(cp, section); // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(func_exe_inst); + UNSERIALIZE_SCALAR(inst); #ifdef FULL_SYSTEM bool ctx; @@ -233,3 +235,16 @@ ExecContext::regStats(const string &name) kernelStats.regStats(name + ".kern"); #endif } + +void +ExecContext::trap(Fault fault) +{ + //TheISA::trap(fault); //One possible way to do it... + + /** @todo: Going to hack it for now. Do a true fixup later. */ +#ifdef FULL_SYSTEM + ev5_trap(fault); +#else + fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); +#endif +} diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 7be83539a..a62225f1b 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -31,6 +31,7 @@ #include "sim/host.hh" #include "mem/mem_req.hh" +#include "mem/functional_mem/functional_memory.hh" #include "sim/serialize.hh" // forward declaration: see functional_memory.hh @@ -114,6 +115,9 @@ class ExecContext // pointer to CPU associated with this context BaseCPU *cpu; + // Current instruction + MachInst inst; + // Index of hardware thread context on the CPU that this represents. int thread_num; @@ -311,6 +315,18 @@ class ExecContext virtual bool misspeculating(); + MachInst getInst() { return inst; } + + void setInst(MachInst new_inst) + { + inst = new_inst; + } + + Fault instRead(MemReqPtr &req) + { + return mem->read(req, inst); + } + // // New accessors for new decoder. // @@ -395,6 +411,14 @@ class ExecContext bool simPalCheck(int palFunc); #endif + /** Meant to be more generic trap function to be + * called when an instruction faults. + * @param fault The fault generated by executing the instruction. + * @todo How to do this properly so it's dependent upon ISA only? + */ + + void trap(Fault fault); + #ifndef FULL_SYSTEM IntReg getSyscallArg(int i) { diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 065140883..05b88b04b 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -708,8 +708,7 @@ SimpleCPU::tick() xc->regs.pc); #ifdef FULL_SYSTEM - xc->regs.opcode = (inst >> 26) & 0x3f; - xc->regs.ra = (inst >> 21) & 0x1f; + xc->setInst(inst); #endif // FULL_SYSTEM xc->func_exe_inst++; diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 57208f8e6..131c5f756 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -43,6 +43,8 @@ class ExecContext; class DynInst; typedef DynInst FullCPUExecContext; +class FastCPU; +typedef FastCPU FastCPUExecContext; class SimpleCPU; typedef SimpleCPU SimpleCPUExecContext; class SymbolTable; @@ -310,6 +312,12 @@ class StaticInst : public StaticInstBase virtual Fault execute(SimpleCPUExecContext *xc, Trace::InstRecord *traceData) = 0; + /** + * Execute this instruction under FastCPU model. + */ + virtual Fault execute(FastCPUExecContext *xc, + Trace::InstRecord *traceData) = 0; + /** * Execute this instruction under detailed FullCPU model. */ -- cgit v1.2.3 From 6964ecd1cf14f294a300e91bc5b65042d03952d4 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Fri, 28 May 2004 14:42:59 -0400 Subject: Updated FastCPU model with all the recent changes. arch/alpha/ev5.cc: Updated to support new forms of setIntReg and setFloatRegDouble. Will need to be cleaned up in the future. arch/isa_parser.py: Added in FastCPU model. --HG-- extra : convert_revision : 384a27efcb50729ea6c3cc11653f395c300e48db --- arch/alpha/ev5.cc | 6 ++++-- arch/isa_parser.py | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index e88f6d0a3..ecf66f4f5 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -153,8 +153,10 @@ void AlphaISA::zeroRegisters(XC *xc) { // Insure ISA semantics - xc->setIntReg(ZeroReg, 0); - xc->setFloatRegDouble(ZeroReg, 0.0); + // (no longer very clean due to the change in setIntReg() in the + // cpu model. Consider changing later.) + xc->xc->setIntReg(ZeroReg, 0); + xc->xc->setFloatRegDouble(ZeroReg, 0.0); } void diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 7f77241be..c808c2565 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -630,6 +630,9 @@ class CpuModel: CpuModel('SimpleCPU', 'simple_cpu_exec.cc', '#include "cpu/simple_cpu/simple_cpu.hh"', { 'CPU_exec_context': 'SimpleCPU' }) +CpuModel('FastCPU', 'fast_cpu_exec.cc', + '#include "cpu/fast_cpu/fast_cpu.hh"', + { 'CPU_exec_context': 'FastCPU' }) CpuModel('FullCPU', 'full_cpu_exec.cc', '#include "cpu/full_cpu/dyn_inst.hh"', { 'CPU_exec_context': 'DynInst' }) -- cgit v1.2.3