sharedmem 0.1.1

Shared memory primitives.
Documentation
use std::sync::atomic::{AtomicUsize, Ordering};

pub struct SpinBarrier {
  counter:  AtomicUsize,
  epoch:    AtomicUsize,
  num_thrs: usize,
}

impl SpinBarrier {
  pub fn new(num_thrs: usize) -> SpinBarrier {
    SpinBarrier{
      counter:  AtomicUsize::new(0),
      epoch:    AtomicUsize::new(0),
      num_thrs: num_thrs,
    }
  }

  pub fn wait(&self) -> bool {
    let prev_epoch = self.epoch.load(Ordering::SeqCst);
    let tid = self.counter.fetch_add(1, Ordering::SeqCst);
    if tid == self.num_thrs - 1 {
      self.counter.store(0, Ordering::SeqCst);
      self.epoch.fetch_add(1, Ordering::SeqCst);
      true
    } else {
      while self.epoch.load(Ordering::SeqCst) == prev_epoch {
      }
      false
    }
  }
}

pub struct SpinSignal {
  counter:  AtomicUsize,
  epoch:    AtomicUsize,
  num_thrs: usize,
}

impl SpinSignal {
  pub fn new(num_thrs: usize) -> SpinSignal {
    SpinSignal{
      counter:  AtomicUsize::new(0),
      epoch:    AtomicUsize::new(0),
      num_thrs: num_thrs,
    }
  }

  pub fn signal(&self) {
    let prev_epoch = self.epoch.load(Ordering::SeqCst);
    self.counter.fetch_add(1, Ordering::SeqCst);
    while self.epoch.load(Ordering::SeqCst) == prev_epoch {
    }
  }

  pub fn maybe_wait(&self) -> bool {
    if self.counter.load(Ordering::SeqCst) == 0 {
      return false;
    }
    let prev_epoch = self.epoch.load(Ordering::SeqCst);
    let tid = self.counter.fetch_add(1, Ordering::SeqCst);
    if tid == self.num_thrs - 1 {
      self.counter.store(0, Ordering::SeqCst);
      self.epoch.fetch_add(1, Ordering::SeqCst);
    } else {
      while self.epoch.load(Ordering::SeqCst) == prev_epoch {
      }
    }
    true
  }
}