Skip to content

Instantly share code, notes, and snippets.

@Lucretiel
Created August 26, 2021 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lucretiel/85c2b85f94abcf92794b073e070ab403 to your computer and use it in GitHub Desktop.
Save Lucretiel/85c2b85f94abcf92794b073e070ab403 to your computer and use it in GitHub Desktop.
An example of a function that processess an atomic as a transaction, using 0 to indicate a locked state
pub fn use_atomic(value: &AtomicU64, op: impl FnOnce(NonZeroU64) -> NonZeroU64) {
loop {
let current = value.swap(0, Ordering::AcqRel);
match NonZeroU64::new(current) {
Some(current) => {
let computed = op(current);
// It might be more appropriate to use compare_exchange here
value.store(computed.get(), Ordering::Release);
break;
}
// Some other thread is currently working with the atomic, give it
// a chance to run
None => yield_now(),
}
}
}
@Lucretiel
Copy link
Author

Some notes:

  • Not reentrant; calling use_atomic from the same thread will deadlock
  • If op panics, the next call to use_atomic will deadlock

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment