starnix_rcu/
rcu_atomic.rs1use starnix_sync::Mutex;
6use starnix_types::atomic::{AsAtomic, AtomicOperations};
7use std::ops::{Deref, DerefMut};
8use std::sync::atomic::Ordering;
9
10#[derive(Debug)]
11pub struct RcuAtomic<T: AsAtomic> {
12 mutex: Mutex<T>,
13 atomic: T::Atomic,
14}
15
16impl<T: AsAtomic> RcuAtomic<T> {
17 pub fn new(value: T) -> Self {
18 Self { mutex: Mutex::new(value), atomic: T::Atomic::new(value) }
19 }
20
21 pub fn read(&self) -> T {
23 self.atomic.load(Ordering::Relaxed)
24 }
25
26 pub fn write(&self, value: T) {
28 let mut guard = self.mutex.lock();
29 *guard = value;
30 self.atomic.store(value, Ordering::Relaxed);
31 }
32
33 pub fn copy(&self) -> RcuAtomicGuard<'_, T> {
36 let guard = self.mutex.lock();
37 RcuAtomicGuard { parent: self, guard }
38 }
39}
40
41pub struct RcuAtomicGuard<'a, T: AsAtomic> {
42 parent: &'a RcuAtomic<T>,
43 guard: starnix_sync::MutexGuard<'a, T>,
44}
45
46impl<'a, T: AsAtomic> Deref for RcuAtomicGuard<'a, T> {
47 type Target = T;
48 fn deref(&self) -> &Self::Target {
49 &*self.guard
50 }
51}
52
53impl<'a, T: AsAtomic> DerefMut for RcuAtomicGuard<'a, T> {
54 fn deref_mut(&mut self) -> &mut Self::Target {
55 &mut *self.guard
56 }
57}
58
59impl<'a, T: AsAtomic> RcuAtomicGuard<'a, T> {
60 pub fn update(self) {
63 let value = *self.guard;
64 self.parent.atomic.store(value, Ordering::Relaxed);
65 }
67}