diff --git a/ostd/src/sync/rcu/mod.rs b/ostd/src/sync/rcu/mod.rs index 782a5163..61ba5b5a 100644 --- a/ostd/src/sync/rcu/mod.rs +++ b/ostd/src/sync/rcu/mod.rs @@ -168,6 +168,22 @@ impl RcuInner

{ _inner_guard: guard, } } + + fn read_with<'a>( + &'a self, + _guard: &'a DisabledPreemptGuard, + ) -> Option<&'a

::Target> { + let obj_ptr = self.ptr.load(Acquire); + if obj_ptr.is_null() { + return None; + } + // SAFETY: + // 1. This pointer is not NULL. + // 2. Since the preemption is disabled, the pointer is valid because + // other writers won't release the allocation until this task passes + // the quiescent state. + Some(unsafe { &*obj_ptr }) + } } impl Drop for RcuInner

{ @@ -250,6 +266,18 @@ impl Rcu

{ pub fn read(&self) -> RcuReadGuard<'_, P> { RcuReadGuard(self.0.read()) } + + /// Reads the RCU-protected value given that preemption is already disabled. + /// + /// If preemption is already disabled, this function can reduce the + /// overhead of disabling preemption again. + /// + /// Unlike [`Self::read`], this function does not return a read guard, so + /// you cannot use [`RcuReadGuard::compare_exchange`] to synchronize the + /// writers. You may do it via a [`super::SpinLock`]. + pub fn read_with<'a>(&'a self, guard: &'a DisabledPreemptGuard) -> &'a

::Target { + self.0.read_with(guard).unwrap() + } } impl RcuOption

{ @@ -292,6 +320,21 @@ impl RcuOption

{ pub fn read(&self) -> RcuOptionReadGuard<'_, P> { RcuOptionReadGuard(self.0.read()) } + + /// Reads the RCU-protected value given that preemption is already disabled. + /// + /// If preemption is already disabled, this function can reduce the + /// overhead of disabling preemption again. + /// + /// Unlike [`Self::read`], this function does not return a read guard, so + /// you cannot use [`RcuOptionReadGuard::compare_exchange`] to synchronize the + /// writers. You may do it via a [`super::SpinLock`]. + pub fn read_with<'a>( + &'a self, + guard: &'a DisabledPreemptGuard, + ) -> Option<&'a

::Target> { + self.0.read_with(guard) + } } // RCU guards that have a non-null pointer can be directly dereferenced.