kperf_sys/functions.rs
1use crate::structs::{kpc_config_t, kpep_config, kpep_db, kpep_event};
2use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, size_t};
3
4#[link(name = "kperf", kind = "framework")]
5extern "C" {
6 /// Print current CPU identification string to the buffer (same as snprintf),
7 /// such as "cpu_7_8_10b282dc_46". This string can be used to locate the PMC
8 /// database in /usr/share/kpep.
9 /// @return string's length, or negative value if error occurs.
10 /// @note This method does not requires root privileges.
11 /// @details sysctl get(hw.cputype), get(hw.cpusubtype),
12 /// get(hw.cpufamily), get(machdep.cpu.model)
13 pub fn kpc_cpu_string(buf: *mut u8, buf_size: size_t) -> c_int;
14 /// Get the version of KPC that's being run.
15 /// @return See `PMU version constants` above.
16 /// @details sysctl get(kpc.pmu_version)
17 pub fn kpc_pmu_version() -> c_uint;
18 /// Get running PMC classes.
19 /// @return See `class mask constants` above,
20 /// 0 if error occurs or no class is set.
21 /// @details sysctl get(kpc.counting)
22 pub fn kpc_get_counting() -> c_uint;
23 /// Set PMC classes to enable counting.
24 /// @param classes See `class mask constants` above, set 0 to shutdown counting.
25 /// @return 0 for success.
26 /// @details sysctl set(kpc.counting)
27 pub fn kpc_set_counting(classes: c_uint) -> c_int;
28 /// Get running PMC classes for current thread.
29 /// @return See `class mask constants` above,
30 /// 0 if error occurs or no class is set.
31 /// @details sysctl get(kpc.thread_counting)
32 pub fn kpc_get_thread_counting() -> c_uint;
33 /// Set PMC classes to enable counting for current thread.
34 /// @param classes See `class mask constants` above, set 0 to shutdown counting.
35 /// @return 0 for success.
36 /// @details sysctl set(kpc.thread_counting)
37 pub fn kpc_set_thread_counting(classes: c_uint) -> c_int;
38 /// Get how many config registers there are for a given mask.
39 /// For example: Intel may returns 1 for `KPC_CLASS_FIXED_MASK`,
40 /// returns 4 for `KPC_CLASS_CONFIGURABLE_MASK`.
41 /// @param classes See `class mask constants` above.
42 /// @return 0 if error occurs or no class is set.
43 /// @note This method does not requires root privileges.
44 /// @details sysctl get(kpc.config_count)
45 pub fn kpc_get_config_count(classes: c_uint) -> c_uint;
46 /// Get config registers.
47 /// @param classes see `class mask constants` above.
48 /// @param config Config buffer to receive values, should not smaller than
49 /// kpc_get_config_count(classes) * sizeof(kpc_config_t).
50 /// @return 0 for success.
51 /// @details sysctl get(kpc.config_count), get(kpc.config)
52 pub fn kpc_get_config(classes: c_uint, config: *mut kpc_config_t) -> c_int;
53 /// Set config registers.
54 /// @param classes see `class mask constants` above.
55 /// @param config Config buffer, should not smaller than
56 /// kpc_get_config_count(classes) * sizeof(kpc_config_t).
57 /// @return 0 for success.
58 /// @details sysctl get(kpc.config_count), set(kpc.config)
59 pub fn kpc_set_config(classes: c_uint, config: *mut kpc_config_t) -> c_int;
60 /// Get how many counters there are for a given mask.
61 /// For example: Intel may returns 3 for `KPC_CLASS_FIXED_MASK`,
62 /// returns 4 for `KPC_CLASS_CONFIGURABLE_MASK`.
63 /// @param classes See `class mask constants` above.
64 /// @note This method does not requires root privileges.
65 /// @details sysctl get(kpc.counter_count)
66 pub fn kpc_get_counter_count(classes: c_uint) -> c_uint;
67 /// Get counter accumulations.
68 /// If `all_cpus` is true, the buffer count should not smaller than
69 /// (cpu_count * counter_count). Otherwize, the buffer count should not smaller
70 /// than (counter_count).
71 /// @see kpc_get_counter_count(), kpc_cpu_count().
72 /// @param all_cpus true for all CPUs, false for current cpu.
73 /// @param classes See `class mask constants` above.
74 /// @param curcpu A pointer to receive current cpu id, can be NULL.
75 /// @param buf Buffer to receive counter's value.
76 /// @return 0 for success.
77 /// @details sysctl get(hw.ncpu), get(kpc.counter_count), get(kpc.counters)
78 pub fn kpc_get_cpu_counters(
79 all_cpus: bool,
80 classes: c_uint,
81 curcpu: *mut c_int,
82 buf: *mut c_ulonglong,
83 ) -> c_int;
84 /// Get counter accumulations for current thread.
85 /// @param tid Thread id, should be 0.
86 /// @param buf_count The number of buf's elements (not bytes),
87 /// should not smaller than kpc_get_counter_count().
88 /// @param buf Buffer to receive counter's value.
89 /// @return 0 for success.
90 /// @details sysctl get(kpc.thread_counters)
91 pub fn kpc_get_thread_counters(tid: c_uint, buf_count: c_uint, buf: *mut c_ulonglong) -> c_int;
92 /// Acquire/release the counters used by the Power Manager.
93 /// @param val 1:acquire, 0:release
94 /// @return 0 for success.
95 /// @details sysctl set(kpc.force_all_ctrs)
96 pub fn kpc_force_all_ctrs_set(val: c_int) -> c_int;
97 /// Get the state of all_ctrs.
98 /// @return 0 for success.
99 /// @details sysctl get(kpc.force_all_ctrs)
100 pub fn kpc_force_all_ctrs_get(val_out: *mut c_int) -> c_int;
101 /// Set number of actions, should be `KPERF_ACTION_MAX`.
102 /// @details sysctl set(kperf.action.count)
103 pub fn kperf_action_count_set(count: c_uint) -> c_int;
104 /// Get number of actions.
105 /// @details sysctl get(kperf.action.count)
106 pub fn kperf_action_count_get(count: *mut c_uint) -> c_int;
107 /// Set what to sample when a trigger fires an action, e.g. `KPERF_SAMPLER_PMC_CPU`.
108 /// @details sysctl set(kperf.action.samplers)
109 pub fn kperf_action_samplers_set(actionid: c_uint, sample: c_uint) -> c_int;
110 /// Get what to sample when a trigger fires an action.
111 /// @details sysctl get(kperf.action.samplers)
112 pub fn kperf_action_samplers_get(actionid: c_uint, sample: *mut c_uint) -> c_int;
113 /// Apply a task filter to the action, -1 to disable filter.
114 /// @details sysctl set(kperf.action.filter_by_task)
115 pub fn kperf_action_filter_set_by_task(actionid: c_uint, port: c_int) -> c_int;
116 /// Apply a pid filter to the action, -1 to disable filter.
117 /// @details sysctl set(kperf.action.filter_by_pid)
118 pub fn kperf_action_filter_set_by_pid(actionid: c_uint, pid: c_int) -> c_int;
119 /// Set number of time triggers, should be `KPERF_TIMER_MAX`.
120 /// @details sysctl set(kperf.timer.count)
121 pub fn kperf_timer_count_set(count: c_uint) -> c_int;
122 /// Get number of time triggers.
123 /// @details sysctl get(kperf.timer.count)
124 pub fn kperf_timer_count_get(count: *mut c_uint) -> c_int;
125 /// Set timer number and period.
126 /// @details sysctl set(kperf.timer.period)
127 pub fn kperf_timer_period_set(actionid: c_uint, tick: c_ulonglong) -> c_int;
128 /// Get timer number and period.
129 /// @details sysctl get(kperf.timer.period)
130 pub fn kperf_timer_period_get(actionid: c_uint, tick: *mut c_ulonglong) -> c_int;
131 /// Set timer number and actionid.
132 /// @details sysctl set(kperf.timer.action)
133 pub fn kperf_timer_action_set(actionid: c_uint, timerid: c_uint) -> c_int;
134 /// Get timer number and actionid.
135 /// @details sysctl get(kperf.timer.action)
136 pub fn kperf_timer_action_get(actionid: c_uint, timerid: *mut c_uint) -> c_int;
137 /// Set which timer ID does PET (Profile Every Thread).
138 /// @details sysctl set(kperf.timer.pet_timer)
139 pub fn kperf_timer_pet_set(timerid: c_uint) -> c_int;
140 /// Get which timer ID does PET (Profile Every Thread).
141 /// @details sysctl get(kperf.timer.pet_timer)
142 pub fn kperf_timer_pet_get(timerid: *mut c_uint) -> c_int;
143 /// Enable or disable sampling.
144 /// @details sysctl set(kperf.sampling)
145 pub fn kperf_sample_set(enabled: c_uint) -> c_int;
146 /// Get is currently sampling.
147 /// @details sysctl get(kperf.sampling)
148 pub fn kperf_sample_get(enabled: *mut c_uint) -> c_int;
149 /// Reset kperf: stop sampling, kdebug, timers and actions.
150 /// @return 0 for success.
151 pub fn kperf_reset() -> c_int;
152 /// Nanoseconds to CPU ticks.
153 pub fn kperf_ns_to_ticks(ns: c_ulonglong) -> c_ulonglong;
154 /// CPU ticks to nanoseconds.
155 pub fn kperf_ticks_to_ns(ticks: c_ulonglong) -> c_ulonglong;
156 /// CPU ticks frequency (mach_absolute_time).
157 pub fn kperf_tick_frequency() -> c_ulonglong;
158}
159
160//TODO: include those two functions to the lib
161// /// Get lightweight PET mode (not in kperf.framework).
162// static int kperf_lightweight_pet_get(u32 *enabled) {
163// if (!enabled) return -1;
164// usize size = 4;
165// return sysctlbyname("kperf.lightweight_pet", enabled, &size, NULL, 0);
166// }
167//
168// /// Set lightweight PET mode (not in kperf.framework).
169// static int kperf_lightweight_pet_set(u32 enabled) {
170// return sysctlbyname("kperf.lightweight_pet", NULL, NULL, &enabled, 4);
171// }
172
173#[link(name = "kperfdata", kind = "framework")]
174extern "C" {
175 /// Create a config.
176 /// @param db A kpep db, see kpep_db_create()
177 /// @param cfg_ptr A pointer to receive the new config.
178 /// @return kpep_config_error_code, 0 for success.
179 pub fn kpep_config_create(db: *mut kpep_db, cfg_ptr: *mut *mut kpep_config) -> c_int;
180
181 /// Free the config.
182 pub fn kpep_config_free(cfg: *mut kpep_config);
183
184 /// Add an event to config.
185 /// @param cfg The config.
186 /// @param ev_ptr A event pointer.
187 /// @param flag 0: all, 1: user space only
188 /// @param err Error bitmap pointer, can be NULL.
189 /// If return value is `CONFLICTING_EVENTS`, this bitmap contains
190 /// the conflicted event indices, e.g. "1 << 2" means index 2.
191 /// @return kpep_config_error_code, 0 for success.
192 pub fn kpep_config_add_event(
193 cfg: *mut kpep_config,
194 ev_ptr: *mut *mut kpep_event,
195 flag: c_uint,
196 err: *mut c_uint,
197 ) -> c_int;
198
199 /// Remove event at index.
200 /// @return kpep_config_error_code, 0 for success.
201 pub fn kpep_config_remove_event(cfg: *mut kpep_config, idx: size_t) -> c_int;
202
203 /// Force all counters.
204 /// @return kpep_config_error_code, 0 for success.
205 pub fn kpep_config_force_counters(cfg: *mut kpep_config) -> c_int;
206
207 /// Get events count.
208 /// @return kpep_config_error_code, 0 for success.
209 pub fn kpep_config_events_count(cfg: *mut kpep_config, count_ptr: *mut size_t) -> c_int;
210
211 /// Get all event pointers.
212 /// @param buf A buffer to receive event pointers.
213 /// @param buf_size The buffer's size in bytes, should not smaller than
214 /// kpep_config_events_count() * sizeof(void *).
215 /// @return kpep_config_error_code, 0 for success.
216 pub fn kpep_config_events(
217 cfg: *mut kpep_config,
218 buf: *mut *mut kpep_event,
219 buf_size: size_t,
220 ) -> c_int;
221
222 /// Get kpc register configs.
223 /// @param buf A buffer to receive kpc register configs.
224 /// @param buf_size The buffer's size in bytes, should not smaller than
225 /// kpep_config_kpc_count() * sizeof(kpc_config_t).
226 /// @return kpep_config_error_code, 0 for success.
227 pub fn kpep_config_kpc(
228 cfg: *mut kpep_config,
229 buf: *mut kpc_config_t,
230 buf_size: size_t,
231 ) -> c_int;
232
233 /// Get kpc register config count.
234 /// @return kpep_config_error_code, 0 for success.
235 pub fn kpep_config_kpc_count(cfg: *mut kpep_config, count_ptr: *mut size_t) -> c_int;
236
237 /// Get kpc classes.
238 /// @param classes See `class mask constants` above.
239 /// @return kpep_config_error_code, 0 for success.
240 pub fn kpep_config_kpc_classes(cfg: *mut kpep_config, classes_ptr: *mut c_uint) -> c_int;
241
242 /// Get the index mapping from event to counter.
243 /// @param buf A buffer to receive indexes.
244 /// @param buf_size The buffer's size in bytes, should not smaller than
245 /// kpep_config_events_count() * sizeof(kpc_config_t).
246 /// @return kpep_config_error_code, 0 for success.
247 pub fn kpep_config_kpc_map(cfg: *mut kpep_config, buf: *mut size_t, buf_size: size_t) -> c_int;
248
249 /// Open a kpep database file in "/usr/share/kpep/" or "/usr/local/share/kpep/".
250 /// @param name File name, for example "haswell", "cpu_100000c_1_92fb37c8".
251 /// Pass NULL for current CPU.
252 /// @return kpep_config_error_code, 0 for success.
253 pub fn kpep_db_create(name: *const c_char, db_ptr: *mut *mut kpep_db) -> c_int;
254
255 /// Free the kpep database.
256 pub fn kpep_db_free(db: *mut kpep_db);
257
258 /// Get the database's name.
259 /// @return kpep_config_error_code, 0 for success.
260 pub fn kpep_db_name(db: *mut kpep_db, name: *const *mut c_char) -> c_int;
261
262 /// Get the event alias count.
263 /// @return kpep_config_error_code, 0 for success.
264 pub fn kpep_db_aliases_count(db: *mut kpep_db, count: *mut size_t) -> c_int;
265
266 /// Get all alias.
267 /// @param buf A buffer to receive all alias strings.
268 /// @param buf_size The buffer's size in bytes,
269 /// should not smaller than kpep_db_aliases_count() * sizeof(void *).
270 /// @return kpep_config_error_code, 0 for success.
271 pub fn kpep_db_aliases(db: *mut kpep_db, buf: *const *mut c_char, buf_size: size_t) -> c_int;
272
273 /// Get counters count for given classes.
274 /// @param classes 1: Fixed, 2: Configurable.
275 /// @return kpep_config_error_code, 0 for success.
276 pub fn kpep_db_counters_count(db: *mut kpep_db, classes: c_uchar, count: *mut size_t) -> c_int;
277
278 /// Get all event count.
279 /// @return kpep_config_error_code, 0 for success.
280 pub fn kpep_db_events_count(db: *mut kpep_db, count: *mut size_t) -> c_int;
281
282 /// Get all events.
283 /// @param buf A buffer to receive all event pointers.
284 /// @param buf_size The buffer's size in bytes,
285 /// should not smaller than kpep_db_events_count() * sizeof(void *).
286 /// @return kpep_config_error_code, 0 for success.
287 pub fn kpep_db_events(db: *mut kpep_db, buf: *mut *mut kpep_event, buf_size: size_t) -> c_int;
288
289 /// Get one event by name.
290 /// @return kpep_config_error_code, 0 for success.
291 pub fn kpep_db_event(
292 db: *mut kpep_db,
293 name: *const c_char,
294 ev_ptr: *mut *mut kpep_event,
295 ) -> c_int;
296
297 /// Get event's name.
298 /// @return kpep_config_error_code, 0 for success.
299 pub fn kpep_event_name(ev: *mut kpep_event, name_ptr: *const *mut c_char) -> c_int;
300
301 /// Get event's alias.
302 /// @return kpep_config_error_code, 0 for success.
303 pub fn kpep_event_alias(ev: *mut kpep_event, alias_ptr: *const *mut c_char) -> c_int;
304
305 /// Get event's description.
306 /// @return kpep_config_error_code, 0 for success.
307 pub fn kpep_event_description(ev: *mut kpep_event, str_ptr: *const *mut c_char) -> c_int;
308}