use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Mutex, Condvar};
use std::thread;
pub trait Latch {
fn set(&self);
}
pub struct SpinLatch {
b: AtomicBool,
}
impl SpinLatch {
#[inline]
pub fn new() -> SpinLatch {
SpinLatch { b: AtomicBool::new(false) }
}
#[inline]
pub fn probe(&self) -> bool {
self.b.load(Ordering::Acquire)
}
#[inline]
pub fn spin(&self) {
while !self.probe() {
thread::yield_now();
}
}
}
impl Latch for SpinLatch {
#[inline]
fn set(&self) {
self.b.store(true, Ordering::Release);
}
}
pub struct LockLatch {
m: Mutex<bool>,
v: Condvar,
}
impl LockLatch {
#[inline]
pub fn new() -> LockLatch {
LockLatch {
m: Mutex::new(false),
v: Condvar::new(),
}
}
pub fn wait(&self) {
let mut guard = self.m.lock().unwrap();
while !*guard {
guard = self.v.wait(guard).unwrap();
}
}
}
impl Latch for LockLatch {
#[inline]
fn set(&self) {
let mut guard = self.m.lock().unwrap();
*guard = true;
self.v.notify_all();
}
}