WIP: rust: sync: rcu: Add example for RCU protected global
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
diff --git a/rust/kernel/sync/rcu.rs b/rust/kernel/sync/rcu.rs
index e969220..281be98 100644
--- a/rust/kernel/sync/rcu.rs
+++ b/rust/kernel/sync/rcu.rs
@@ -233,6 +233,65 @@ pub fn dereference<'rcu>(&self, _rcu_guard: &'rcu Guard) -> Option<P::Borrowed<'
/// [`Opaque<T>`] which has the same effect on aliasing rules as [`UnsafePinned`].
///
/// [`UnsafePinned`]: https://rust-lang.github.io/rfcs/3467-unsafe-pinned.html
+ ///
+ /// ```
+ /// use kernel::prelude::*;
+ ///
+ /// use kernel::sync::{GlobalGuard, ProjectableGlobalLockedBy, rcu::{Rcu, read_lock}};
+ /// use kernel::{alloc::{KBox, KVec}, error::Error};
+ /// use core::ops::Deref;
+ ///
+ /// kernel::sync::global_lock! {
+ /// // SAFETY: Initialized in module initializer before first use.
+ /// pub unsafe(uninit) static MY_MUTEX: Mutex<()> = ();
+ /// }
+ ///
+ /// static POLICY: ProjectableGlobalLockedBy<Rcu<KBox<KVec<u32>>>, MY_MUTEX> = ProjectableGlobalLockedBy::new(Rcu::null());
+ ///
+ /// // SAFETY: initialize one time.
+ /// unsafe { MY_MUTEX.init() };
+ ///
+ ///
+ /// // Two readers
+ /// let r1 = POLICY.deref();
+ /// let r2 = POLICY.deref();
+ ///
+ /// let mut g = MY_MUTEX.lock();
+ ///
+ /// let mut w = POLICY.as_mut(&mut g);
+ ///
+ /// w.as_mut().read_copy_update(|_| {
+ /// let mut vec = kernel::kvec![];
+ ///
+ /// vec.push(1, GFP_KERNEL).ok()?;
+ ///
+ /// KBox::new(vec, GFP_KERNEL).ok()
+ /// });
+ ///
+ /// let rcu_guard = read_lock();
+ /// let v = r1.dereference(&rcu_guard);
+ ///
+ /// assert_eq!(v, Some(&(kernel::kvec![1]?)));
+ ///
+ /// drop(rcu_guard);
+ ///
+ /// w.read_copy_update(|old| {
+ /// let mut vec = kernel::kvec![];
+ ///
+ /// vec.extend_from_slice(old?.as_slice(), GFP_KERNEL).ok()?;
+ /// vec.push(2, GFP_KERNEL).ok()?;
+ ///
+ /// KBox::new(vec, GFP_KERNEL).ok()
+ /// });
+ ///
+ /// let rcu_guard = read_lock();
+ /// let v = r2.dereference(&rcu_guard);
+ ///
+ /// assert_eq!(v, Some(&(kernel::kvec![1, 2]?)));
+ ///
+ /// drop(rcu_guard);
+ /// # Ok::<(), Error>(())
+ /// ```
pub fn read_copy_update<F>(self: Pin<&mut Self>, f: F) -> Option<RcuOld<P>>
where
F: FnOnce(Option<P::Borrowed<'_>>) -> Option<P>,