static void pctrrd(struct pctrst *st) { int i, num, reg; num = pctr_isamd ? PCTR_AMD_NUM : PCTR_INTEL_NUM; reg = pctr_isamd ? MSR_K7_EVNTSEL0 : MSR_EVNTSEL0; for (i = 0; i < num; i++) st->pctr_fn[i] = rdmsr(reg + i); __asm volatile("cli"); st->pctr_tsc = rdtsc(); for (i = 0; i < num; i++) st->pctr_hwc[i] = rdpmc(i); __asm volatile("sti"); }
/* From Peter Zijlstra's demo code */ unsigned long long mmap_read_self(void *addr, unsigned long long *enabled, unsigned long long *running) { struct perf_event_mmap_page *pc = addr; unsigned int seq; unsigned long long count, delta=0, cyc; unsigned long long rem, quot; do { again: seq=pc->lock; barrier(); if (seq&1) goto again; if ((enabled || running) && pc->time_mult) { cyc = rdtsc(); quot=(cyc >> pc->time_shift); rem = cyc & ((1 << pc->time_shift) -1); delta=pc->time_offset + quot*pc->time_mult + ((rem * pc->time_mult) >> pc->time_shift); } if (enabled) *enabled=pc->time_enabled+delta; if (running) *running=pc->time_running+delta; if (pc->index) { count=rdpmc(pc->index-1); count+=pc->offset; } else goto fail; barrier(); } while (pc->lock != seq);
inline uint64_t rdmpc64(uint32_t counter) { UInt32 lo,hi; rdpmc(counter, lo, hi); return ((UInt64)hi << 32 ) | lo; }