blob: 35b98abdf296147bd6aeb9fc24b467ecde7d1897 [file]
// Copyright 2026 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
use super::handle::KernelHandle;
use super::timer_dispatcher::{OnTimerFiredAction, TimerDispatcher, TimerDispatcherState};
use core::mem::MaybeUninit;
use zx_types::{zx_clock_t, zx_status_t};
// C++ FFI declarations
unsafe extern "C" {
pub(crate) fn cpp_timer_dispatcher_create(
options: u32,
clock_id: zx_clock_t,
handle_out: *mut MaybeUninit<KernelHandle<TimerDispatcher>>,
) -> zx_status_t;
pub(crate) fn cpp_timer_dispatcher_init_dpc(
dpc_storage: *mut core::ffi::c_void,
disp: *const TimerDispatcher,
);
pub(crate) fn timer_irq_callback(
timer: *mut crate::kernel::timer::Timer,
now: i64,
arg: *mut core::ffi::c_void,
);
}
// Trampolines from C++ into Rust TimerDispatcher / TimerDispatcherState
/// # Safety
///
/// `ptr` must point to uninitialized memory of at least `size_of::<TimerDispatcherState>()`
/// bytes with proper alignment, and `dispatcher` points to the enclosing C++ `TimerDispatcher`.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust_timer_dispatcher_state_init(
ptr: *mut TimerDispatcherState,
dispatcher: *const TimerDispatcher,
options: u32,
clock_id: zx_clock_t,
) {
unsafe {
let _ = pin_init::PinInit::__pinned_init(
TimerDispatcherState::init(dispatcher, options, clock_id),
ptr,
);
}
}
/// # Safety
///
/// `disp` must be a valid reference to an initialized `TimerDispatcher`.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust_timer_dispatcher_on_zero_handles(disp: &TimerDispatcher) {
disp.on_zero_handles();
}
/// # Safety
///
/// `disp` must be a valid pointer to an initialized `TimerDispatcher`.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust_timer_dispatcher_on_timer_fired(disp: *const TimerDispatcher) {
let disp = unsafe { fbl::RefPtr::from_raw(disp) };
match disp.on_timer_fired() {
OnTimerFiredAction::ReleaseRef => {}
OnTimerFiredAction::RetainRef => core::mem::forget(disp),
}
}
/// # Safety
///
/// `disp` must be a valid reference to an initialized `TimerDispatcher`.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust_timer_dispatcher_get_info(
disp: &TimerDispatcher,
) -> zx_types::zx_info_timer_t {
disp.get_info()
}