[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Rust in QEMU roadmap
From: |
Paolo Bonzini |
Subject: |
Re: Rust in QEMU roadmap |
Date: |
Sun, 1 Dec 2024 13:16:00 +0100 |
On Tue, Nov 26, 2024 at 6:48 PM Paolo Bonzini <pbonzini@redhat.com> wrote:
> Callbacks
> '''''''''
>
> This is the least mature of the "urgent" changes, and perhaps the more
> important to have a good design for. PL011 has callbacks for character
> devices and memory regions, but other usecases include timers, bottom
> halves and interrupt sinks (aka GPIO inputs).
Ok, I have an idea that should make it possible to write something like this:
pub struct Timer {
t: *mut QEMUTimer,
}
impl Timer {
// FnCall is QEMU-specific and contains all the magic.
unsafe extern "C" fn rust_timer_cb<
'a, T, F: FnCall<(&'a T,)>>(opaque: *mut c_void) {
// The argument to F::call is a tuple, otherwise this is fairly expected
F::call((unsafe { &*(opaque.cast::<T>()) },))
}
#[inline]
fn new_ns<'a, T, F: FnCall<(&'a T,)>>(
clk: QEMUClockType,
_cb: F,
opaque: &'a T,
) -> Timer {
let cb: unsafe extern "C" fn(*mut c_void) = rust_timer_cb::<'a, T, F>;
Timer {
t: unsafe { bindings::timer_new_ns(clk, cb, opaque) },
}
}
}
and then the caller can simply write
self.timer = Timer::new_ns(QEMU_CLOCK_VIRTUAL, Self::timer_update, self);
The idea is that the compiler will generate a different version of
rust_timer_cb for every value of the second argument (which is unused,
except inasmuch as it helps the compiler know what "F::call" means).
In the code above "unsafe" is only needed for the unavoidable casts
and FFI calls, while the device has no unsafe at all. I haven't
written the timer bindings but the basic idea is like the above. It
can be expanded once Zhao posts his HPET conversion.
It may also be possible to use macros to make things a little less
verbose, but I'm tending to err on the side of explicitness for now.
I'm also not sure about the applicability of this trick to character
devices and memory regions, since those have multiple callbacks and/or
callbacks in structs rather than function parameters. However, for
timers this is a good option I think.
Paolo
- Re: Rust in QEMU roadmap,
Paolo Bonzini <=