lace-ws 1.0.0

work-stealing library based on the lace deque
Documentation
use std::sync::atomic::{AtomicUsize, Ordering};

#[derive(Default)]
pub struct Metrics {
    pub tasks: AtomicUsize,
    pub leap_success: AtomicUsize,
    pub leap_busy: AtomicUsize,
    pub leap_empty: AtomicUsize,
    pub steal_success: AtomicUsize,
    pub steal_busy: AtomicUsize,
    pub steal_empty: AtomicUsize,
    #[cfg(not(feature = "chase_lev"))]
    pub splitreqs: AtomicUsize,
    #[cfg(not(feature = "chase_lev"))]
    pub shrink_not_allstolen1: AtomicUsize,
    #[cfg(not(feature = "chase_lev"))]
    pub shrink_not_allstolen2: AtomicUsize,
    #[cfg(not(feature = "chase_lev"))]
    pub shrink_allstolen: AtomicUsize,
    #[cfg(not(feature = "chase_lev"))]
    pub shrink_fix_tail: AtomicUsize,
    #[cfg(not(feature = "chase_lev"))]
    pub grows: AtomicUsize,
}

impl std::fmt::Debug for Metrics {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        let tasks = self.tasks.load(Ordering::Relaxed);
        let leap_s = self.leap_success.load(Ordering::Relaxed);
        let leap_b = self.leap_busy.load(Ordering::Relaxed);
        let leap_e = self.leap_empty.load(Ordering::Relaxed);
        let steal_s = self.steal_success.load(Ordering::Relaxed);
        let steal_b = self.steal_busy.load(Ordering::Relaxed);
        let steal_e = self.steal_empty.load(Ordering::Relaxed);
        #[cfg(feature = "chase_lev")]
        {
            write!(
                f,
                "[tasks:{tasks}, leaps:(success:{leap_s}, busy:{leap_b}, empty:{leap_e}), steals:(success:{steal_s}, busy:{steal_b}, empty:{steal_e})]",
            )
        }
        #[cfg(not(feature = "chase_lev"))]
        {
            write!(f, "[tasks:{tasks}, leaps:(success:{leap_s}, busy:{leap_b}, empty:{leap_e}), steals:(success:{steal_s}, busy:{steal_b}, empty:{steal_e}), splitreq set:{}, grows:{}, shrinks:(as:{}, !as1:{}, !as2:{}, fix tail:{})]",
                   self.splitreqs.load(Ordering::Relaxed),
                   self.grows.load(Ordering::Relaxed),
                   self.shrink_allstolen.load(Ordering::Relaxed),
                   self.shrink_not_allstolen1.load(Ordering::Relaxed),
                   self.shrink_not_allstolen2.load(Ordering::Relaxed),
                   self.shrink_fix_tail.load(Ordering::Relaxed),
            )
        }
    }
}

impl Metrics {
    pub fn normalized(&self, factor: usize) -> Self {
        macro_rules! normalize {
            ($field:ident) => {
                AtomicUsize::new(self.$field.load(Ordering::Relaxed) / factor)
            };
        }
        Self {
            tasks: normalize!(tasks),
            leap_success: normalize!(leap_success),
            leap_busy: normalize!(leap_busy),
            leap_empty: normalize!(leap_empty),
            steal_success: normalize!(steal_success),
            steal_busy: normalize!(steal_busy),
            steal_empty: normalize!(steal_empty),
            #[cfg(not(feature = "chase_lev"))]
            splitreqs: normalize!(splitreqs),
            #[cfg(not(feature = "chase_lev"))]
            shrink_not_allstolen1: normalize!(shrink_not_allstolen1),
            #[cfg(not(feature = "chase_lev"))]
            shrink_not_allstolen2: normalize!(shrink_not_allstolen2),
            #[cfg(not(feature = "chase_lev"))]
            shrink_allstolen: normalize!(shrink_allstolen),
            #[cfg(not(feature = "chase_lev"))]
            shrink_fix_tail: normalize!(shrink_fix_tail),
            #[cfg(not(feature = "chase_lev"))]
            grows: normalize!(grows),
        }
    }
    pub fn add_into(&self, other: &mut Metrics) {
        macro_rules! process {
            () => {};
            ($field:ident $(, $rest:ident)*) => {{
                other.$field.fetch_add(self.$field.load(Ordering::Relaxed), Ordering::Relaxed);
                process!($($rest),*);
            }};
        }
        process!(
            tasks,
            leap_success,
            leap_busy,
            leap_empty,
            steal_success,
            steal_busy,
            steal_empty
        );
        #[cfg(not(feature = "chase_lev"))]
        {
            process!(
                splitreqs,
                shrink_not_allstolen1,
                shrink_not_allstolen2,
                shrink_allstolen,
                shrink_fix_tail,
                grows
            );
        }
    }
}