Struct incr::AtomicIncr

source ·
pub struct AtomicIncr(/* private fields */);
Expand description

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.

Examples

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);

Implementations§

source§

impl AtomicIncr

source

pub fn is_new(&self, val: u64) -> bool

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.

source

pub fn get(&self) -> u64

Returns the current value of self, which is the maximum observed value.

source

pub fn into_inner(self) -> Arc<AtomicU64>

Consumes the outer struct, returning the inner Arc<Atomic>.

Trait Implementations§

source§

impl Clone for AtomicIncr

source§

fn clone(&self) -> AtomicIncr

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for AtomicIncr

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for AtomicIncr

source§

fn default() -> AtomicIncr

Returns the “default value” for a type. Read more
source§

impl From<u64> for AtomicIncr

source§

fn from(val: u64) -> Self

Converts to this type from the input type.
source§

impl PartialEq<AtomicIncr> for AtomicIncr

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<AtomicIncr> for AtomicIncr

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl Eq for AtomicIncr

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere 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 Twhere 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> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

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

§

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 Twhere U: TryFrom<T>,

§

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.