1//===- Perf.inc ----------------------------------------------------------===// 2// 3// The SkyPat Team 4// 5// This file is distributed under the New BSD License. 6// See LICENSE for details. 7// 8//===----------------------------------------------------------------------===// 9#include <skypat/Support/ManagedStatic.h> 10#include <time.h> 11#include <unistd.h> 12#include <cassert> 13 14#if defined(HAVE_LINUX_PERF_EVENT_H) 15#include <linux/perf_event.h> 16#include <sys/ioctl.h> 17#include <cstring> 18#include <cstdlib> 19#if defined(HAVE_ASM_UNISTD_H) 20#include <asm/unistd.h> 21#endif 22#endif 23 24#ifndef SKYPAT_SKYPAT_H 25#include <skypat/skypat.h> 26#endif 27 28namespace skypat { 29namespace testing { 30namespace internal { 31 32//===----------------------------------------------------------------------===// 33// Perf Implementation 34//===----------------------------------------------------------------------===// 35class PerfImpl 36{ 37public: 38 PerfImpl() { 39 } 40 ~PerfImpl() { 41#if defined(HAVE_LINUX_PERF_EVENT_H) 42 close(m_Fd); 43#endif 44 } 45 46 testing::Interval getCounter() { 47#if defined(HAVE_LINUX_PERF_EVENT_H) 48 unsigned long long counter; 49 read(m_Fd, &counter, sizeof(unsigned long long)); 50 return counter; 51#else 52 return 0; 53#endif 54 return -1; 55 } 56 57 void init(enum PerfEvent pEvent) { 58#if defined(HAVE_LINUX_PERF_EVENT_H) 59 60 /* store the perf event numbers with the same order of skypat:Perf_event_name */ 61 static const decltype(perf_event_attr::config) 62 event_list[] = { 63 PERF_COUNT_HW_CPU_CYCLES, PERF_COUNT_HW_INSTRUCTIONS, 64 PERF_COUNT_HW_CACHE_REFERENCES, PERF_COUNT_HW_CACHE_MISSES, 65 PERF_COUNT_HW_BRANCH_INSTRUCTIONS, PERF_COUNT_HW_BRANCH_MISSES, 66 PERF_COUNT_HW_BUS_CYCLES, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND, 67 PERF_COUNT_HW_STALLED_CYCLES_BACKEND, PERF_COUNT_HW_REF_CPU_CYCLES, 68 PERF_COUNT_SW_CPU_CLOCK, PERF_COUNT_SW_TASK_CLOCK, 69 PERF_COUNT_SW_PAGE_FAULTS, PERF_COUNT_SW_CONTEXT_SWITCHES, 70 PERF_COUNT_SW_CPU_MIGRATIONS, PERF_COUNT_SW_PAGE_FAULTS_MIN, 71 PERF_COUNT_SW_PAGE_FAULTS_MAJ, PERF_COUNT_SW_ALIGNMENT_FAULTS, 72 PERF_COUNT_SW_EMULATION_FAULTS, 73#ifdef PERF_COUNT_SW_DUMMY 74 PERF_COUNT_SW_DUMMY 75#else 76 0 77#endif 78 }; 79 80 struct perf_event_attr attr; 81 82 memset(&attr, 0, sizeof(attr)); 83 84 attr.inherit = 1; 85 attr.disabled = 1; 86 87 attr.config = event_list[pEvent]; 88 89 if(pEvent < PerfEvent::CPU_CLOCK) 90 attr.type = PERF_TYPE_HARDWARE; 91 else 92 attr.type = PERF_TYPE_SOFTWARE; 93 94 attr.size = sizeof(attr); 95 96 m_Fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); 97#endif 98 } 99 100 void start() { 101#if defined(HAVE_LINUX_PERF_EVENT_H) 102 ioctl(m_Fd, PERF_EVENT_IOC_ENABLE); 103#endif 104 m_Start = getCounter(); 105 assert(-1 != m_Start && "fail to get performance counters"); 106 } 107 108 void stop() { 109#if defined(HAVE_LINUX_PERF_EVENT_H) 110 ioctl(m_Fd, PERF_EVENT_IOC_DISABLE); 111#endif 112 m_End = getCounter(); 113 assert(-1 != m_End && "fail to get performance counters"); 114 } 115 116 testing::Interval getValue() const { 117 return (m_End - m_Start); 118 } 119 120private: 121 testing::Interval m_Start; 122 testing::Interval m_End; 123 124 static long g_ClkTick; 125 126 int m_Fd; 127}; 128 129long PerfImpl::g_ClkTick = -1; 130 131static ManagedStatic<PerfImpl> g_Perf; 132 133//===----------------------------------------------------------------------===// 134// Perf 135//===----------------------------------------------------------------------===// 136Perf::Perf() 137 : m_Interval(0), m_EventType(PerfEvent::CONTEXT_SWITCHES), m_bIsActive(false) { 138 g_Perf->init(PerfEvent::CONTEXT_SWITCHES); 139} 140 141Perf::Perf(enum PerfEvent pEvent) 142 : m_Interval(0), m_EventType(pEvent), m_bIsActive(false) { 143 g_Perf->init(pEvent); 144} 145 146Perf::~Perf() 147{ 148} 149 150void Perf::start() 151{ 152 m_bIsActive = true; 153 g_Perf->start(); 154} 155 156void Perf::stop() 157{ 158 g_Perf->stop(); 159 m_bIsActive = false; 160 m_Interval = g_Perf->getValue(); 161} 162 163std::string Perf::unit() 164{ 165 return "times"; 166} 167 168} // namespace of internal 169} // namespace of testing 170} // namespace of skypat 171