rt 0.19.1

A real-time operating system capable of full preemption
Documentation
#![no_main]
#![cfg_attr(target_os = "none", no_std)]

rt::mutex!(MUTEX, u32, 0);

const NUM_TASKS: u32 = 3;
const ITERATIONS: u32 = 10000;

fn exit_last() {
    rt::sem!(EXIT_SEM, NUM_TASKS as i32 - 1);
    if !EXIT_SEM.try_wait() {
        assert_eq!(
            *MUTEX.try_lock().expect("mutex should be unlocked"),
            ITERATIONS * NUM_TASKS,
            "the mutex did not contain the expected value"
        );
        rt::exit();
    }
}

fn increment_lock() {
    rt::task::drop_privilege();
    for _ in 0..ITERATIONS {
        *MUTEX.lock() += 1;
    }
    exit_last();
}

fn increment_trylock() {
    rt::task::drop_privilege();
    for _ in 0..ITERATIONS {
        let mut guard = loop {
            if let Some(guard) = MUTEX.try_lock() {
                break guard;
            } else {
                rt::task::sleep(1);
            }
        };
        *guard += 1;
    }
    exit_last();
}

fn increment_timedlock() {
    rt::task::drop_privilege();
    for _ in 0..ITERATIONS {
        let mut guard = loop {
            if let Some(guard) = MUTEX.timed_lock(1) {
                break guard;
            }
        };
        *guard += 1;
    }
    exit_last();
}

fn timeout() {
    rt::task::sleep(1000);
    panic!("timed out");
}

const STACK_SIZE: usize = rt::stack::MIN * 8;

rt::task!(increment_lock, STACK_SIZE, 1);
rt::task!(increment_trylock, STACK_SIZE, 1);
rt::task!(increment_timedlock, STACK_SIZE, 1);
rt::task!(timeout, STACK_SIZE, 0);