39 #define CFGWORD_EL0A64EN_MASK (0x20000)
40 #define CPMU_CORE_CYCLE 0x02
41 #define KPC_CLASS_FIXED_MASK (1 << 0)
42 #define KPC_CLASS_CONFIGURABLE_MASK (1 << 1)
43 #define COUNTERS_COUNT 10
44 #define CONFIG_COUNT 8
45 #define KPC_MASK (KPC_CLASS_CONFIGURABLE_MASK | KPC_CLASS_FIXED_MASK)
47 static int (*kpc_get_thread_counters)(int,
unsigned int,
void *);
50 static inline uint64_t kperf_cycles(
void)
52 uint64_t counters[COUNTERS_COUNT];
53 if (kpc_get_thread_counters(0, COUNTERS_COUNT, counters))
59 static uint64_t perf_start(
void)
61 return kperf_cycles();
64 static uint64_t perf_stop(uint64_t t)
66 return kperf_cycles() - t;
71 uint64_t
config[COUNTERS_COUNT] = { 0 };
77 = dlopen(
"/System/Library/PrivateFrameworks/kperf.framework/kperf", RTLD_LAZY);
79 fprintf(stderr,
"checkasm: Unable to load kperf: %s\n", dlerror());
83 int (*kpc_force_all_ctrs_set)(int) = dlsym(kperf,
"kpc_force_all_ctrs_set");
84 int (*kpc_set_counting)(uint32_t) = dlsym(kperf,
"kpc_set_counting");
85 int (*kpc_set_thread_counting)(uint32_t) = dlsym(kperf,
"kpc_set_thread_counting");
86 int (*kpc_set_config)(uint32_t,
void *) = dlsym(kperf,
"kpc_set_config");
87 uint32_t (*kpc_get_counter_count)(uint32_t) = dlsym(kperf,
"kpc_get_counter_count");
88 uint32_t (*kpc_get_config_count)(uint32_t) = dlsym(kperf,
"kpc_get_config_count");
89 kpc_get_thread_counters = dlsym(kperf,
"kpc_get_thread_counters");
91 if (!kpc_get_thread_counters) {
92 fprintf(stderr,
"checkasm: Unable to load kpc_get_thread_counters\n");
96 if (!kpc_get_counter_count || kpc_get_counter_count(
KPC_MASK) != COUNTERS_COUNT) {
97 fprintf(stderr,
"checkasm: Unexpected kpc_get_counter_count\n");
101 fprintf(stderr,
"checkasm: Unexpected kpc_get_config_count\n");
108 fprintf(stderr,
"checkasm: The kperf API needs to be run as root\n");
111 if (!kpc_force_all_ctrs_set || kpc_force_all_ctrs_set(1)) {
112 fprintf(stderr,
"checkasm: kpc_force_all_ctrs_set failed\n");
115 if (!kpc_set_counting || kpc_set_counting(
KPC_MASK)) {
116 fprintf(stderr,
"checkasm: kpc_set_counting failed\n");
119 if (!kpc_set_counting || kpc_set_thread_counting(
KPC_MASK)) {
120 fprintf(stderr,
"checkasm: kpc_set_thread_counting failed\n");
126 perf->
start = perf_start;
127 perf->
stop = perf_stop;
128 perf->
name =
"macOS (kperf)";
129 perf->
unit =
"cycle";