starnix_rcu/
rcu_atomic.rs1use starnix_sync::{LockDepGuard, LockDepMutex, LockLevel};
6use starnix_types::atomic::{AsAtomic, AtomicOperations};
7use std::ops::{Deref, DerefMut};
8use std::sync::atomic::Ordering;
9
10pub struct RcuAtomic<T: AsAtomic, L: LockLevel> {
11 mutex: LockDepMutex<T, L>,
12 atomic: T::Atomic,
13}
14
15impl<T: AsAtomic + std::fmt::Debug, L: LockLevel> std::fmt::Debug for RcuAtomic<T, L> {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 f.debug_struct("RcuAtomic").field("value", &self.read()).finish()
18 }
19}
20
21impl<T: AsAtomic, L: LockLevel> RcuAtomic<T, L> {
22 pub fn new(value: T) -> Self {
23 Self { mutex: LockDepMutex::new(value), atomic: T::Atomic::new(value) }
24 }
25
26 pub fn read(&self) -> T {
28 self.atomic.load(Ordering::Relaxed)
29 }
30
31 pub fn write(&self, value: T) {
33 let mut guard = self.mutex.lock();
34 *guard = value;
35 self.atomic.store(value, Ordering::Relaxed);
36 }
37
38 pub fn copy(&self) -> RcuAtomicGuard<'_, T, L> {
41 let guard = self.mutex.lock();
42 RcuAtomicGuard { parent: self, guard }
43 }
44}
45
46pub struct RcuAtomicGuard<'a, T: AsAtomic, L: LockLevel> {
47 parent: &'a RcuAtomic<T, L>,
48 guard: LockDepGuard<'a, T>,
49}
50
51impl<'a, T: AsAtomic, L: LockLevel> Deref for RcuAtomicGuard<'a, T, L> {
52 type Target = T;
53 fn deref(&self) -> &Self::Target {
54 &*self.guard
55 }
56}
57
58impl<'a, T: AsAtomic, L: LockLevel> DerefMut for RcuAtomicGuard<'a, T, L> {
59 fn deref_mut(&mut self) -> &mut Self::Target {
60 &mut *self.guard
61 }
62}
63
64impl<'a, T: AsAtomic, L: LockLevel> RcuAtomicGuard<'a, T, L> {
65 pub fn update(self) {
68 let value = *self.guard;
69 self.parent.atomic.store(value, Ordering::Relaxed);
70 }
72}