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}