1#include <stdbool.h> 2#include <errno.h> 3 4#include <linux/perf_event.h> 5 6#include "../../perf.h" 7#include <linux/types.h> 8#include "../../util/debug.h" 9#include "../../util/tsc.h" 10#include "tsc.h" 11 12int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, 13 struct perf_tsc_conversion *tc) 14{ 15 bool cap_user_time_zero; 16 u32 seq; 17 int i = 0; 18 19 while (1) { 20 seq = pc->lock; 21 rmb(); 22 tc->time_mult = pc->time_mult; 23 tc->time_shift = pc->time_shift; 24 tc->time_zero = pc->time_zero; 25 cap_user_time_zero = pc->cap_user_time_zero; 26 rmb(); 27 if (pc->lock == seq && !(seq & 1)) 28 break; 29 if (++i > 10000) { 30 pr_debug("failed to get perf_event_mmap_page lock\n"); 31 return -EINVAL; 32 } 33 } 34 35 if (!cap_user_time_zero) 36 return -EOPNOTSUPP; 37 38 return 0; 39} 40 41u64 rdtsc(void) 42{ 43 unsigned int low, high; 44 45 asm volatile("rdtsc" : "=a" (low), "=d" (high)); 46 47 return low | ((u64)high) << 32; 48} 49