[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC 07/13] rust: add bindings for timer
From: |
Zhao Liu |
Subject: |
Re: [RFC 07/13] rust: add bindings for timer |
Date: |
Tue, 14 Jan 2025 23:36:48 +0800 |
Hi Paolo,
Thanks for your FnCall and the guidance below...
> This gets tricky when you have more than one timer per device. With the right
> infrastructure we can make this something like
>
> fn timer_init_full<'a, 'b: 'a, T, F: 'b Fn(&'b T)>(
> &'a mut self,
> timer_list_group: Option<&mut QEMUTimerListGroup>,
> clk_type: QEMUClockType,
> scale: u32,
> attributes: u32,
> f: &F,
> opaque: &'b T) {
> // SAFETY: the opaque outlives the timer
> unsafe {
> timer_init_full(...)
> }
> }
...
> pub struct Clock {
> id: QEMUClockType
> }
>
> impl Clock {
> pub fn get_ns() -> u64 {
> // SAFETY: cannot be created outside this module, therefore id
> // is valid
> (unsafe { qemu_clock_get_ns(self.id) }) as u64
> }
> }
>
> pub static CLOCK_VIRTUAL: Clock = Clock { id:
> QEMUClockType::QEMU_CLOCK_VIRTUAL };
> // etc.
>
> and then the user can do timer::CLOCK_VIRTUAL::get_ns().
>
...Now I have a draft for timer binding:
* timer binding:
impl QEMUTimer {
pub fn new() -> Self {
Zeroable::ZERO
}
pub fn timer_init_full<'a, 'b: 'a, T, F>(
&'a mut self,
timer_list_group: Option<&mut QEMUTimerListGroup>,
clk_type: QEMUClockType,
scale: u32,
attributes: u32,
_f: &F,
opaque: &'b T,
) where
F: for<'c> FnCall<(&'c T,)> + 'b,
{
let timer_cb: unsafe extern "C" fn(*mut c_void) =
rust_timer_handler::<T, F>;
// SAFETY: the opaque outlives the timer
unsafe {
timer_init_full(
self,
if let Some(g) = timer_list_group {
g
} else {
::core::ptr::null_mut()
},
clk_type,
scale as c_int,
attributes as c_int,
Some(timer_cb),
opaque as *const T as *const c_void as *mut c_void,
)
}
}
pub fn timer_mod(&mut self, expire_time: u64) {
unsafe { timer_mod(self as *mut QEMUTimer, expire_time as i64) }
}
}
* use of timer binding:
fn timer_handler(timer_cell: &BqlRefCell<HPETTimer>) {
timer_cell.borrow_mut().callback()
}
impl HPETTimer {
...
fn init_timer_with_state(&mut self) {
let index = self.index;
let cb = |cell: &BqlRefCell<HPETTimer>| {
timer_handler(cell);
};
self.qemu_timer = Some(Box::new({
let mut t = QEMUTimer::new();
t.timer_init_full(
None,
CLOCK_VIRTUAL.id,
SCALE_NS,
0,
&cb,
&self.get_state().timer[index],
);
t
}));
}
...
}
---
Is this timer binding as you expected? Hope I am on the right track. :-)
Thanks,
Zhao
- Re: [RFC 07/13] rust: add bindings for timer,
Zhao Liu <=