Merged head into linux tree
base/stats/mysql.hh:
Rename of Statsistics namespace to stats... merge from head
--HG--
extra : convert_revision : a5a7f6268b35e75fba1b1800a74fcd6dbd09d974
This commit is contained in:
@@ -440,8 +440,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
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
/* $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 "cpu/fast_cpu/fast_cpu.hh"
|
||||
#include "sim/debug.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
|
||||
#ifdef FULL_SYSTEM
|
||||
|
||||
@@ -99,9 +99,71 @@ AlphaISA::initIPRs(RegFile *regs)
|
||||
}
|
||||
|
||||
|
||||
template <class XC>
|
||||
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 <class XC>
|
||||
void
|
||||
AlphaISA::zeroRegisters(XC *xc)
|
||||
{
|
||||
// Insure ISA semantics
|
||||
// (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
|
||||
ExecContext::ev5_trap(Fault fault)
|
||||
{
|
||||
Stats::recordEvent(csprintf("Fault %s", FaultName(fault)));
|
||||
|
||||
assert(!misspeculating());
|
||||
kernelStats.fault(fault);
|
||||
|
||||
@@ -581,4 +643,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
|
||||
|
||||
@@ -75,6 +75,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
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <class XC>
|
||||
static void zeroRegisters(XC *xc);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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' })
|
||||
@@ -1057,10 +1060,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 +1077,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 +1110,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 +1133,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
|
||||
|
||||
105
base/stats/events.cc
Normal file
105
base/stats/events.cc
Normal file
@@ -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<string, uint32_t> 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)
|
||||
panic("could not get a run\n%s\n", mysql.error);
|
||||
|
||||
assert(result.num_fields() == 1);
|
||||
MySQL::Row row = result.fetch_row();
|
||||
if (row) {
|
||||
if (!to_number(row[0], event))
|
||||
panic("invalid event id: %s\n", row[0]);
|
||||
} else {
|
||||
mysql.query(
|
||||
csprintf("INSERT INTO "
|
||||
"event_names(en_name)"
|
||||
"values(\"%s\")",
|
||||
stat));
|
||||
|
||||
if (mysql.error)
|
||||
panic("could not get a run\n%s\n", mysql.error);
|
||||
|
||||
event = mysql.insert_id();
|
||||
}
|
||||
} else {
|
||||
event = (*i).second;
|
||||
}
|
||||
|
||||
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 */ }
|
||||
63
base/stats/events.hh
Normal file
63
base/stats/events.hh
Normal file
@@ -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 <string>
|
||||
|
||||
#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__
|
||||
@@ -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<int, int> 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 "
|
||||
@@ -119,6 +134,16 @@ Cleanup(MySqlData *data)
|
||||
"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
|
||||
@@ -142,9 +167,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 +270,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 +317,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 +345,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 +357,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 +375,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 +389,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 +405,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<int,int>::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 +423,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 +451,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 +470,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 +487,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 +502,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 +513,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 +524,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 +535,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 +548,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 +559,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 +589,6 @@ MySql::output()
|
||||
configure();
|
||||
|
||||
// store sample #
|
||||
newdata.run = run_id;
|
||||
newdata.sample = curTick;
|
||||
|
||||
if (bins().empty()) {
|
||||
@@ -781,7 +720,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());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#ifndef __BASE_STATS_MYSQL_HH__
|
||||
#define __BASE_STATS_MYSQL_HH__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/stats/output.hh"
|
||||
@@ -37,7 +38,9 @@ namespace MySQL { class Connection; }
|
||||
namespace Stats {
|
||||
|
||||
class DistDataData;
|
||||
class MySqlData;
|
||||
class MySqlRun;
|
||||
bool MySqlConnected();
|
||||
extern MySqlRun MySqlDB;
|
||||
|
||||
struct SetupStat
|
||||
{
|
||||
@@ -58,7 +61,7 @@ struct SetupStat
|
||||
uint16_t size;
|
||||
|
||||
void init();
|
||||
unsigned operator()(MySqlData *data);
|
||||
unsigned setup();
|
||||
};
|
||||
|
||||
class InsertData
|
||||
@@ -70,14 +73,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 +94,28 @@ class InsertData
|
||||
class MySql : public Output
|
||||
{
|
||||
protected:
|
||||
std::list<FormulaData *> formulas;
|
||||
MySqlData *mysql;
|
||||
bool configured;
|
||||
uint16_t run_id;
|
||||
|
||||
SetupStat stat;
|
||||
InsertData newdata;
|
||||
std::list<FormulaData *> formulas;
|
||||
bool configured;
|
||||
|
||||
void insert(int sim_id, int db_id);
|
||||
int find(int sim_id);
|
||||
protected:
|
||||
std::map<int, int> 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<int,int>::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);
|
||||
|
||||
63
base/stats/mysql_run.hh
Normal file
63
base/stats/mysql_run.hh
Normal file
@@ -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 <string>
|
||||
|
||||
#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__
|
||||
@@ -101,6 +101,7 @@ baseFlags = [
|
||||
'Chains',
|
||||
'Dispatch',
|
||||
'Stats',
|
||||
'StatEvents',
|
||||
'Context',
|
||||
'Config',
|
||||
'Sampler',
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -707,8 +714,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++;
|
||||
|
||||
@@ -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<TheISA> *si, int idx)
|
||||
{
|
||||
return xc->readIntReg(si->srcRegIdx(idx));
|
||||
}
|
||||
|
||||
double readFloatRegDouble(int reg_idx)
|
||||
{ return xc->readFloatRegDouble(reg_idx); }
|
||||
float readFloatRegSingle(StaticInst<TheISA> *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<TheISA> *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<TheISA> *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<TheISA> *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<TheISA> *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<TheISA> *si, int idx, double val)
|
||||
{
|
||||
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
|
||||
xc->setFloatRegDouble(reg_idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegInt(StaticInst<TheISA> *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(); }
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
// forward declarations
|
||||
class ExecContext;
|
||||
class DynInst;
|
||||
class FastCPU;
|
||||
class SimpleCPU;
|
||||
class SymbolTable;
|
||||
|
||||
@@ -106,11 +107,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 +195,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.
|
||||
@@ -309,6 +313,11 @@ class StaticInst : public StaticInstBase
|
||||
*/
|
||||
virtual Fault execute(SimpleCPU *xc, Trace::InstRecord *traceData) = 0;
|
||||
|
||||
/**
|
||||
* Execute this instruction under FastCPU model.
|
||||
*/
|
||||
virtual Fault execute(FastCPU *xc, Trace::InstRecord *traceData) = 0;
|
||||
|
||||
/**
|
||||
* Execute this instruction under detailed FullCPU model.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user