How to mplement rcu-like lockless mechanisms?

Hi all,

let's say I have a main thread that allocates an immutable data structure and stores a pointer to it into a variable "p". A second thread then periodically makes a copy of the structure pointed by "p" and works on it. At some point, the main thread can allocate a new data structure and change the value of "p" to point to the new structure (so, at the next periodic activation the second thread will work on the new structure).
I have an implementation based on an Arc containing a Mutex that contains another Arc:

struct S<T> {
  p: std::sync::Arc<std::sync::Mutex<std::sync::Arc<T>>>,
}
  
impl<T> S<T> {
  fn new(my_v: T) -> S<T> {
    S {p: std::sync::Arc::new(std::sync::Mutex::new(std::sync::Arc::new(my_v)))}
  }
  fn clone(&self) -> S<T> {
    S {p: self.p.clone()}
  }
  fn get_s(&self) -> std::sync::Arc<T> {
    self.p.lock().unwrap().clone()
  }
  fn set_s(&mut self, new_v: T) {
    *self.p.lock().unwrap() = std::sync::Arc::new(new_v)
  }
}

(the second thread gets a clone() of S, and periodically invokes get_s(), while the main thread can do set_s())

But I am wondering if it is possible to create a lockless version of this... I tried using AtomicPtr, but this forced me to use unsafe code. Can something like this be implemented lockless without using unsafe?

Thanks,
Luca

You are probably looking for arc-swap.

Thanks for the reference! I previously looked at various "rcu*" crates but missed arc-swap...
Now, I am looking at it, and I see it uses AtomicPtr and unsafe blocks. So, I guess there really is no way to make this code lockless without using unsafe.

Thanks,
Luca

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.