On 11/19/25 16:17, Zhao Liu wrote:
-    fn init_timer_with_cell(cell: &BqlRefCell<Self>) {
-        let mut timer = cell.borrow_mut();
-        // SAFETY: HPETTimer is only used as part of HPETState, which is
-        // always pinned.
-        let qemu_timer = unsafe { Pin::new_unchecked(&mut timer.qemu_timer) };
-        qemu_timer.init_full(None, CLOCK_VIRTUAL, Timer::NS, 0, timer_handler, 
cell);
+    fn init_timer(timer: Pin<&mut Self>) {
+        Timer::init_full(
+            timer,
+            None,
+            CLOCK_VIRTUAL,
+            Timer::NS,
+            0,
+            timer_handler,
+            |t| &mut t.qemu_timer,
+        );
      }

I find this way could also work for BqlRefCell case:

     fn init_timer_with_cell(cell: &mut BqlRefCell<Self>) {
         // SAFETY: HPETTimer is only used as part of HPETState, which is
         // always pinned.
         let timer = unsafe { Pin::new_unchecked(cell) };
         Timer::init_full(
             timer,
             None,
             CLOCK_VIRTUAL,
             Timer::NS,
             0,
             timer_handler,
             |t| {
                 assert!(bql::is_locked());
                 &mut t.get_mut().qemu_timer
             },
         );
     }

Yes, but I'm still not sure what the final shape will be... I don't like this too much.


So any other non-lockless timer can also use this interface to
initialize their BqlRefCell<>.

(BTW, I find BqlRefCell::get_mut() / as_ref() missed bql::is_locked().
  right?)

as_ptr() doesn't need it because the pointer can be dereferenced later.

As to get_mut()... I think if you are the only owner, you should have the guarantee of being able to modify the content freely. This is true even if your &mut came from interior mutability.

So, in the above case you only need &mut t.get_mut().qemu_timer.

I think it may be better to add doc about how to use this for
BqlRefCell<> case since there'll be no example after this patch.


Reply via email to