Struct RcuCell

Source
pub struct RcuCell<T> { /* private fields */ }
Expand description

A concurrent data structure that allows for safe, read-copy-update (RCU) style access to its value.

Implementations§

Source§

impl<T> RcuCell<T>

Source

pub fn new(value: T) -> Self

Creates a new RcuCell with the given initial value.

This function initializes a new RcuCell instance, setting its initial value to the provided value.

§Arguments
  • value - The initial value to store in the RcuCell.
§Returns

A new instance of RcuCell containing the provided initial value.

§Example
let rcu_cell = rcu_128::RcuCell::new(42);
Examples found in repository?
examples/example.rs (line 6)
5fn main() {
6    let x = rcu_128::RcuCell::new(0);
7    std::thread::scope(|s| {
8        s.spawn(|| {
9            for i in 0..40 {
10                let t = Instant::now();
11                if i < 20 {
12                    x.write(i);
13                } else {
14                    x.update(|v| v + 1);
15                }
16                println!("Update {i} used time: {:?}", t.elapsed());
17                sleep((t + Duration::from_millis(100)).duration_since(Instant::now()));
18            }
19        });
20        s.spawn(|| {
21            // Always has 4 guards alive
22            let mut guards = [x.read(), x.read(), x.read(), x.read()];
23            for idx in 0..400 {
24                let r = x.read();
25                println!("Read value: {}", *r);
26                guards[idx % 4] = r;
27                sleep(Duration::from_millis(10));
28            }
29        });
30    })
31}
Source

pub fn read(&self) -> RcuGuard<'_, T>

Provides read access to the value stored in the RcuCell.

This function returns an RcuGuard, which allows for safe, concurrent read access to the RcuCell’s value.

Once all RcuGuard instances referencing a particular value are dropped, the value can be safely released during an update or write.

§Example
let rcu_cell = rcu_128::RcuCell::new(42);
{
    let guard = rcu_cell.read();
    assert_eq!(*guard, 42);
}
Examples found in repository?
examples/example.rs (line 22)
5fn main() {
6    let x = rcu_128::RcuCell::new(0);
7    std::thread::scope(|s| {
8        s.spawn(|| {
9            for i in 0..40 {
10                let t = Instant::now();
11                if i < 20 {
12                    x.write(i);
13                } else {
14                    x.update(|v| v + 1);
15                }
16                println!("Update {i} used time: {:?}", t.elapsed());
17                sleep((t + Duration::from_millis(100)).duration_since(Instant::now()));
18            }
19        });
20        s.spawn(|| {
21            // Always has 4 guards alive
22            let mut guards = [x.read(), x.read(), x.read(), x.read()];
23            for idx in 0..400 {
24                let r = x.read();
25                println!("Read value: {}", *r);
26                guards[idx % 4] = r;
27                sleep(Duration::from_millis(10));
28            }
29        });
30    })
31}
Source

pub fn write(&self, value: T)

Writes a new value into the RcuCell.

This function immediately writes the new value into the RcuCell. It will block until all current readers have finished reading the old value.

Once all readers have completed their read operations, the old value will be safely released.

§Arguments
  • value - The new value to store in the RcuCell.
§Example
let rcu_cell = rcu_128::RcuCell::new(42);
rcu_cell.write(100);
{
    let guard = rcu_cell.read();
    assert_eq!(*guard, 100);
}
Examples found in repository?
examples/example.rs (line 12)
5fn main() {
6    let x = rcu_128::RcuCell::new(0);
7    std::thread::scope(|s| {
8        s.spawn(|| {
9            for i in 0..40 {
10                let t = Instant::now();
11                if i < 20 {
12                    x.write(i);
13                } else {
14                    x.update(|v| v + 1);
15                }
16                println!("Update {i} used time: {:?}", t.elapsed());
17                sleep((t + Duration::from_millis(100)).duration_since(Instant::now()));
18            }
19        });
20        s.spawn(|| {
21            // Always has 4 guards alive
22            let mut guards = [x.read(), x.read(), x.read(), x.read()];
23            for idx in 0..400 {
24                let r = x.read();
25                println!("Read value: {}", *r);
26                guards[idx % 4] = r;
27                sleep(Duration::from_millis(10));
28            }
29        });
30    })
31}
Source

pub fn update(&self, f: impl FnOnce(&T) -> T)

Updates the value stored in the RcuCell using a provided function.

This function applies the given closure f to the current value stored in the RcuCell, replacing it with the new value returned by the closure. It will block until all current readers have finished reading the old value.

Once all readers have completed their read operations, the old value will be safely released.

§Arguments
  • f - A closure that takes a reference to the current value and returns a new value to store in the RcuCell.
§Example
let rcu_cell = rcu_128::RcuCell::new(42);
rcu_cell.update(|&old_value| old_value + 1);
{
    let guard = rcu_cell.read();
    assert_eq!(*guard, 43);
}
Examples found in repository?
examples/example.rs (line 14)
5fn main() {
6    let x = rcu_128::RcuCell::new(0);
7    std::thread::scope(|s| {
8        s.spawn(|| {
9            for i in 0..40 {
10                let t = Instant::now();
11                if i < 20 {
12                    x.write(i);
13                } else {
14                    x.update(|v| v + 1);
15                }
16                println!("Update {i} used time: {:?}", t.elapsed());
17                sleep((t + Duration::from_millis(100)).duration_since(Instant::now()));
18            }
19        });
20        s.spawn(|| {
21            // Always has 4 guards alive
22            let mut guards = [x.read(), x.read(), x.read(), x.read()];
23            for idx in 0..400 {
24                let r = x.read();
25                println!("Read value: {}", *r);
26                guards[idx % 4] = r;
27                sleep(Duration::from_millis(10));
28            }
29        });
30    })
31}

Auto Trait Implementations§

§

impl<T> !Freeze for RcuCell<T>

§

impl<T> !RefUnwindSafe for RcuCell<T>

§

impl<T> Send for RcuCell<T>
where T: Send,

§

impl<T> Sync for RcuCell<T>
where T: Sync,

§

impl<T> Unpin for RcuCell<T>
where T: Unpin,

§

impl<T> UnwindSafe for RcuCell<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.