Skip to main content

darwin_kperf/framework/
mod.rs

1//! RAII handles for Apple's private performance counter frameworks.
2//!
3//! [`KPerf`] wraps `kperf.framework` (counter configuration and sampling) and
4//! [`KPerfData`] wraps `kperfdata.framework` (PMC event database and
5//! configuration building). Both load their framework at construction via
6//! `dlopen` and resolve all required symbols eagerly into a
7//! [`VTable`](darwin_kperf_sys::kperf::VTable).
8//!
9//! You normally don't construct these directly. [`Sampler::new`](crate::Sampler::new)
10//! creates both handles internally. If you need the raw function pointers for
11//! something the safe API doesn't expose, you can access them through
12//! [`Sampler::kperf`](crate::Sampler::kperf) and
13//! [`Sampler::kperfdata`](crate::Sampler::kperfdata).
14
15mod error;
16
17use core::ffi::CStr;
18
19use darwin_kperf_sys::load::{LibraryHandle, LoadError};
20
21pub use self::error::{FrameworkError, FrameworkErrorKind};
22
23/// Handle to Apple's private `kperf.framework`.
24///
25/// Owns the dynamically loaded library and its resolved
26/// [`VTable`](darwin_kperf_sys::kperf::VTable), which has the KPC function
27/// pointers for counter configuration, sampling, and tick/nanosecond
28/// conversion.
29#[derive(Debug)]
30pub struct KPerf {
31    _handle: LibraryHandle,
32    vtable: darwin_kperf_sys::kperf::VTable,
33}
34
35impl KPerf {
36    /// Loads `kperf.framework` from its default system path.
37    ///
38    /// # Errors
39    ///
40    /// Returns [`LoadError`] if the framework cannot be loaded or any required symbol
41    /// cannot be resolved.
42    pub fn new() -> Result<Self, LoadError> {
43        Self::load(c"/System/Library/PrivateFrameworks/kperf.framework/kperf")
44    }
45
46    /// Loads `kperf.framework` from a custom `path`.
47    ///
48    /// # Errors
49    ///
50    /// Returns [`LoadError`] if the framework cannot be loaded or any required symbol
51    /// cannot be resolved.
52    pub fn load(path: &CStr) -> Result<Self, LoadError> {
53        let handle = LibraryHandle::open(path)?;
54        let vtable = darwin_kperf_sys::kperf::VTable::load(&handle)?;
55
56        Ok(Self {
57            _handle: handle,
58            vtable,
59        })
60    }
61
62    /// Resolved vtable for the loaded `kperf.framework`.
63    #[must_use]
64    pub const fn vtable(&self) -> &darwin_kperf_sys::kperf::VTable {
65        &self.vtable
66    }
67}
68
69/// Handle to Apple's private `kperfdata.framework`.
70///
71/// Owns the dynamically loaded library and its resolved
72/// [`VTable`](darwin_kperf_sys::kperfdata::VTable). The vtable contains the
73/// KPEP functions for opening the PMC event database for the current CPU,
74/// looking up events by name or alias, and building the register configuration
75/// that gets pushed to the kernel via [`KPerf`].
76#[derive(Debug)]
77pub struct KPerfData {
78    _handle: LibraryHandle,
79    vtable: darwin_kperf_sys::kperfdata::VTable,
80}
81
82impl KPerfData {
83    /// Loads `kperfdata.framework` from its default system path.
84    ///
85    /// # Errors
86    ///
87    /// Returns [`LoadError`] if the framework cannot be loaded or any required symbol
88    /// cannot be resolved.
89    pub fn new() -> Result<Self, LoadError> {
90        Self::load(c"/System/Library/PrivateFrameworks/kperfdata.framework/kperfdata")
91    }
92
93    /// Loads `kperfdata.framework` from a custom `path`.
94    ///
95    /// # Errors
96    ///
97    /// Returns [`LoadError`] if the framework cannot be loaded or any required symbol
98    /// cannot be resolved.
99    pub fn load(path: &CStr) -> Result<Self, LoadError> {
100        let handle = LibraryHandle::open(path)?;
101        let vtable = darwin_kperf_sys::kperfdata::VTable::load(&handle)?;
102
103        Ok(Self {
104            _handle: handle,
105            vtable,
106        })
107    }
108
109    /// Resolved vtable for the loaded `kperfdata.framework`.
110    #[must_use]
111    pub const fn vtable(&self) -> &darwin_kperf_sys::kperfdata::VTable {
112        &self.vtable
113    }
114}