use std::ffi::{c_long, c_void};
mod ffi {
use std::ffi::c_long;
#[link(name = "android")]
unsafe extern "C" {
pub fn APerformanceHint_getManager() -> *mut std::ffi::c_void;
pub fn APerformanceHint_createSession(
manager: *mut std::ffi::c_void,
thread_ids: *const i32,
size: usize,
initial_target_work_duration_ns: c_long,
) -> *mut std::ffi::c_void;
pub fn APerformanceHint_reportActualWorkDuration(
session: *mut std::ffi::c_void,
actual_duration_ns: c_long,
);
pub fn APerformanceHint_closeSession(session: *mut std::ffi::c_void);
}
}
pub struct AdpfSession {
session: *mut c_void,
}
impl AdpfSession {
pub fn new(target_ns: i64, tid: Option<i32>) -> Option<Self> {
let session = unsafe {
let manager = ffi::APerformanceHint_getManager();
if manager.is_null() {
return None;
}
let tid = tid.unwrap_or_else(|| libc::syscall(libc::SYS_gettid) as i32);
let s = ffi::APerformanceHint_createSession(manager, &tid, 1, target_ns as c_long);
if s.is_null() {
return None;
}
s
};
Some(Self { session })
}
pub fn report(&self, dur_ns: i64) {
unsafe {
ffi::APerformanceHint_reportActualWorkDuration(self.session, dur_ns as c_long);
}
}
}
impl Drop for AdpfSession {
fn drop(&mut self) {
unsafe {
ffi::APerformanceHint_closeSession(self.session);
}
}
}