From 4c55d26e664f870d56889097939569c4b07c6de2 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 18 May 2004 16:09:02 -0700 Subject: [PATCH 01/14] 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 f964101df7..8641c2880f 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; + // check to see if simulator wants to do something special + // on this PAL call (including maybe suppress it) + bool dopal = xc->simPalCheck(palFunc); - 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); - } - } - - // 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 1065fa3d48..088fdbdb7d 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. From 27a6e8258dabef233bc1681649b871bf150878ed Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 18 May 2004 22:09:13 -0700 Subject: [PATCH 02/14] 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 6217207096..7f77241bed 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 a04dcd057a..0c7204fcd9 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). - float readFloatRegSingle(int reg_idx) - { return xc->readFloatRegSingle(reg_idx); } + uint64_t readIntReg(StaticInst *si, int idx) + { + return xc->readIntReg(si->srcRegIdx(idx)); + } - double readFloatRegDouble(int reg_idx) - { return xc->readFloatRegDouble(reg_idx); } + float readFloatRegSingle(StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegSingle(reg_idx); + } - uint64_t readFloatRegInt(int reg_idx) - { return xc->readFloatRegInt(reg_idx); } + double readFloatRegDouble(StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegDouble(reg_idx); + } - void setIntReg(int reg_idx, uint64_t val) - { return xc->setIntReg(reg_idx, val); } + uint64_t readFloatRegInt(StaticInst *si, int idx) + { + int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; + return xc->readFloatRegInt(reg_idx); + } - void setFloatRegSingle(int reg_idx, float val) - { return xc->setFloatRegSingle(reg_idx, val); } + void setIntReg(StaticInst *si, int idx, uint64_t val) + { + xc->setIntReg(si->destRegIdx(idx), val); + } - void setFloatRegDouble(int reg_idx, double val) - { return xc->setFloatRegDouble(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 setFloatRegInt(int reg_idx, uint64_t val) - { return xc->setFloatRegInt(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(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(); } From 2cf71ff6efb61b619aa059c279942355080acb44 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 19 May 2004 21:54:05 -0400 Subject: [PATCH 03/14] Replaced by python --HG-- extra : convert_revision : 5c95c2b3169b8b1a51166d7f8fcde3de39fa30f9 From 47604c8c89539df9aa27b7ba5c4523f27a8ec243 Mon Sep 17 00:00:00 2001 From: Erik Hallnor Date: Thu, 20 May 2004 23:26:44 -0400 Subject: [PATCH 04/14] Update the adaptive cache compression scheme. --HG-- extra : convert_revision : 50c158b0545c29c03e346f1bd2952951ac77659b From b4405682d9f0d7bd01ff461a7e457f8dbbfff1a0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 21 May 2004 13:03:17 -0400 Subject: [PATCH 05/14] 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 | 30 +++++++++++++++--------------- base/sat_counter.cc | 4 ++-- base/sat_counter.hh | 32 ++++++++++++++++---------------- 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, 136 insertions(+), 136 deletions(-) diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 12196c44be..b5fc182552 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 0a5c5b0065..12dacebd93 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 12bab975b5..41cf88675a 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 9063f3084a..a76977ae2e 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 + 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 - 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::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 a8367d8a0c..09c8881a54 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 a5d9c7e8aa..68addbb338 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 + 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 - Statistics::Scalar<> record_zero; //updates_zero - Statistics::Scalar<> record_one; //updates_one + Stats::Scalar<> record_zero; //updates_zero + Stats::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::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 1a44cd3426..78012bff73 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 ee09cc6224..bd1698ae7e 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 2303de1725..b86f87d251 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 676bc555c2..c16332d1b3 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 4ff474752b..dd88f57242 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 9f1fbf4152..186d7bab13 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 f54272a50a..cd5a095c0a 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 fb672e1dc3..6935a9aa0f 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 79a91e6611..511dbe6383 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 89bddf0cb8..88e32ff0ab 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 4451c4e6ee..dcfbd5fa92 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 fec11b2620..88cd466b4d 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 a03842c52b..3a46bb9ef3 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 624023f0af..702a9afe8a 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 c4826cf15e..9c4026784f 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 a89cf4bb52..7f7719bf00 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 5d608976da..1d745724fb 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 f2409d54c0..4bde5c0662 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 617c91e680..7655073459 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 0c7204fcd9..1c6b18d039 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 fdf2a06c9c..dba3f326c2 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 8861f3ef0b..032a05668d 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 c6b497343e..65cb8409f7 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 b23302b8f6..d235f0ef1b 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 9626c54ea7..7f756858c1 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 c7d2fdd5bc..28ee348b5b 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 9a5e269e1b..56170dc776 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 c5e791cfb3..218036eb66 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 791a092acc..619593abd3 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 564579fe48..b839458848 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 9b7ba98579..1a035859a1 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); From fee1e1ec0a9c1122f3c42fdef9482c64389949fc Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 21 May 2004 13:57:44 -0400 Subject: [PATCH 06/14] 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 | 201 +++++++++++++--------------------------- base/stats/mysql.hh | 42 +++++---- 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 0000000000..3a858611f4 --- /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 0000000000..49c0606459 --- /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 c16332d1b3..05808c211a 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 -{ - map idmap; - MySQL::Connection conn; -}; +MySqlRun MySqlDB; -int -SetupRun(MySqlData *data, const string &name, const string &user, - const string &project) +bool +MySqlConnected() +{ + return MySqlDB.connected(); +} + +void +MySqlRun::connect(const string &host, const string &user, const string &passwd, + const string &db, const string &name, const string &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 dd88f57242..4671b89dd0 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 0000000000..0f8d84297a --- /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 b7b7fa777e..69f4e7ab85 100644 --- a/base/traceflags.py +++ b/base/traceflags.py @@ -100,6 +100,7 @@ baseFlags = [ 'Chains', 'Dispatch', 'Stats', + 'StatEvents', 'Context', 'Config', 'Sampler', From f622d74f81f6d0c451bc8437d19a38057bc0d164 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 21 May 2004 13:58:39 -0400 Subject: [PATCH 07/14] 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 | 19 ++++++++++--------- cpu/simple_cpu/simple_cpu.cc | 7 +++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index f037a34ac5..96d54c54c6 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 "cpu/exec_context.hh" -#include "sim/sim_events.hh" -#include "targetarch/isa_traits.hh" +#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/kgdb.h" // for ALPHA_KENTRY_IF -#include "targetarch/osfpal.hh" +#include "base/stats/events.hh" +#include "cpu/exec_context.hh" +#include "sim/debug.hh" +#include "sim/sim_events.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 7655073459..1ade235ed8 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; } From 6cf04bf31e97cde528ad7eee18abdf64fcdfde42 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 21 May 2004 15:06:04 -0400 Subject: [PATCH 08/14] fix column name for indexes --HG-- extra : convert_revision : 34831eed6b218e470096f010438fd2f32a4960c5 From 3a0dfc43d19255a04c74ef1b1017e978bc5b8796 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 23 May 2004 12:53:34 -0400 Subject: [PATCH 09/14] 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 3a858611f4..b579981e91 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 05808c211a..77366beb08 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 From c5c45335967e827e9681af5f8167b10d39348ff8 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 27 May 2004 14:06:29 -0400 Subject: [PATCH 10/14] config_files.doxygen: Apparently <> don't need backslashes if they're inside dbl-quoted strings. --HG-- extra : convert_revision : dd5294781d0ef818d1a5b622f3415510baefb402 From 12c6bef21a33d24286626ec3add6cb38a4963650 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 27 May 2004 14:12:49 -0400 Subject: [PATCH 11/14] postint, postext: Fix output path /m5 -> /z/m5 --HG-- extra : convert_revision : 11ebcc7e62f02be8b0aeb8857eebc33a27e29513 From 4f34dda81cf26340b9446e5a15bbbcd8840b92a2 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 27 May 2004 14:20:50 -0400 Subject: [PATCH 12/14] test to see if pushing to m5-tru64 triggers an e-mail --HG-- extra : convert_revision : df7aab669a8521d031c7202e36c3c086fa979854 From a896960cbfce76a0e0c8cfb5cbdfc805ce72577b Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 27 May 2004 17:46:16 -0400 Subject: [PATCH 13/14] 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 1608cc4a48..23815bf01b 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 9b3ac5fff7..fe665abe62 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 aa3d7e226c..6947ef7081 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 0d1e7138f7..016040b79d 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 05ab899781..37ba77192b 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 0ee9e2e2d9..cc42657e2c 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 a89cf4bb52..832a621f81 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 7be83539a9..a62225f1b5 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 0651408836..05b88b04bc 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 57208f8e6f..131c5f7566 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. */ From 6964ecd1cf14f294a300e91bc5b65042d03952d4 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Fri, 28 May 2004 14:42:59 -0400 Subject: [PATCH 14/14] 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 e88f6d0a3a..ecf66f4f51 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 7f77241bed..c808c25654 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' })