lowlet 0.1.2

Low-latency IPC library using shared memory and lock-free structures
Documentation
use lowlet::buf::RingBuffer;
use lowlet::lf::SpscQueue;
use lowlet::sync::Spinlock;

#[test]
fn test_ring_buffer_send_recv() {
    let buf = RingBuffer::<u64, 8>::new();

    buf.send(1).unwrap();
    buf.send(2).unwrap();
    buf.send(3).unwrap();

    assert_eq!(buf.recv().unwrap(), 1);
    assert_eq!(buf.recv().unwrap(), 2);
    assert_eq!(buf.recv().unwrap(), 3);
}

#[test]
fn test_ring_buffer_capacity() {
    let buf = RingBuffer::<u64, 4>::new();

    for i in 0..4 {
        buf.send(i).unwrap();
    }

    assert!(buf.send(100).is_err());
}

#[test]
fn test_ring_buffer_wraparound() {
    let buf = RingBuffer::<u64, 4>::new();

    for i in 0..10 {
        buf.send(i).unwrap();
        assert_eq!(buf.recv().unwrap(), i);
    }
}

#[test]
fn test_spsc_queue_basic() {
    let q = SpscQueue::<u32, 16>::new();

    q.push(1).unwrap();
    q.push(2).unwrap();

    assert_eq!(q.pop().unwrap(), 1);
    assert_eq!(q.len(), 1);
    assert!(!q.is_empty());
}

#[test]
fn test_spsc_queue_empty() {
    let q = SpscQueue::<u32, 8>::new();

    assert!(q.is_empty());
    assert!(q.pop().is_err());
}

#[test]
fn test_spsc_queue_wraparound() {
    let q = SpscQueue::<u64, 8>::new();

    for cycle in 0..3 {
        for i in 0..8 {
            q.push(cycle * 8 + i).unwrap();
        }
        for i in 0..8 {
            assert_eq!(q.pop().unwrap(), cycle * 8 + i);
        }
    }
}

#[test]
fn test_spinlock_basic() {
    let lock = Spinlock::new(42u64);

    {
        let guard = lock.lock();
        assert_eq!(*guard, 42);
    }

    {
        let mut guard = lock.lock();
        *guard = 100;
    }

    assert_eq!(*lock.lock(), 100);
}

#[test]
fn test_spinlock_try_lock() {
    let lock = Spinlock::new(0u32);

    let guard1 = lock.try_lock();
    assert!(guard1.is_some());

    let guard2 = lock.try_lock();
    assert!(guard2.is_none());

    drop(guard1);

    let guard3 = lock.try_lock();
    assert!(guard3.is_some());
}