pub struct AtomicIncr(_);
AtomicIncr
is a threadsafe, yet very fast counter, utilizing compare
and swap instructions to provide speed and safety in the same package.
There are some cases where 5ns matters. But in many, many other
situations, it's a perfectly good decision to just use the AtomicIncr
,
knowing it can handle anything, and move on to other problems.
use std::thread::{spawn, JoinHandle};
use std::sync::{Arc, Barrier};
use incr::AtomicIncr;
let last: AtomicIncr = Default::default();
let barrier = Arc::new(Barrier::new(2));
let thread: JoinHandle<u64> = {
let barrier = Arc::clone(&barrier);
let last = last.clone();
spawn(move || {
assert_eq!(last.is_new(2), true);
assert_eq!(last.is_new(3), true);
assert_eq!(last.is_new(3), false);
barrier.wait();
last.get()
})
};
barrier.wait();
assert_eq!(last.is_new(3), false);
assert_eq!(thread.join().unwrap(), 3);
It's also possible to access the inner Arc<AtomicU64>
by consuming the
outer wrapper:
use incr::AtomicIncr;
#[cfg(feature = "nightly")]
type Atomic = AtomicU64;
#[cfg(not(feature = "nightly"))]
type Atomic = AtomicUsize;
let stop = Arc::new(AtomicBool::new(false));
let last: AtomicIncr = Default::default();
let mut threads = Vec::new();
for _ in 0..5 {
let val: Arc<Atomic> = last.clone().into_inner();
let stop = Arc::clone(&stop);
threads.push(thread::spawn(move || {
loop {
val.fetch_add(1, Ordering::Relaxed);
thread::yield_now();
if stop.load(Ordering::Relaxed) { break }
}
}));
}
let mut i = 1;
for _ in 0..100 {
i = match last.is_new(i) {
true => i + 1,
false => i.max(last.get()),
};
}
stop.store(true, Ordering::SeqCst);
Returns true
if val
is greater than the highest previously observed
value. If val
is a new maximum, it is stored in self
for checks against
future values subsequent calls Self::get(&self)
will return val
until a
new max is observed.
Returns the current value of self
, which is the maximum observed value.
Consumes the outer struct, returning the inner Arc<Atomic>
.
Returns the "default value" for a type. Read more
Performs copy-assignment from source
. Read more
Formats the value using the given formatter. Read more
This method tests for self
and other
values to be equal, and is used by ==
. Read more
This method tests for !=
.
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
This method tests greater than or equal to (for self
and other
) and is used by the >=
operator. Read more