parkring 0.4.0

Bounded MPMC queues (Vyukov and SCQ), a Chase-Lev work-stealing deque and a work-stealing thread pool, with futex-based parking, verified with loom and Miri.
Documentation
//! Compile-time thread-safety contract. The negative cases (`Rc<T>` is not
//! accepted) are `compile_fail` doctests in `src/lib.rs`.

use std::cell::Cell;

use parkring::{BlockingQueue, BoundedQueue, LockFreeQueue, ScqQueue, Stealer, Worker};

fn assert_send_sync<T: Send + Sync>() {}

#[test]
fn queues_are_send_and_sync_for_send_items() {
    assert_send_sync::<LockFreeQueue<String>>();
    assert_send_sync::<BlockingQueue<String>>();
    // `T: Send` is enough: items are moved between threads, never shared.
    assert_send_sync::<LockFreeQueue<Cell<u32>>>();
    assert_send_sync::<BlockingQueue<Cell<u32>>>();
    assert_send_sync::<ScqQueue<String>>();
    assert_send_sync::<ScqQueue<Cell<u32>>>();
}

fn assert_send<T: Send>() {}

#[test]
fn deque_handles_have_the_right_auto_traits() {
    assert_send::<Worker<String>>();
    assert_send_sync::<Stealer<String>>();
    assert_send_sync::<Stealer<Cell<u32>>>();
}

#[test]
fn trait_is_object_safe() {
    let queues: Vec<Box<dyn BoundedQueue<u32>>> = vec![
        Box::new(LockFreeQueue::new(2)),
        Box::new(BlockingQueue::new(2)),
    ];
    for q in &queues {
        q.push(1).unwrap();
        assert_eq!(q.pop(), Ok(1));
    }
}