rt 0.19.1

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

use core::sync::atomic::{AtomicI32, Ordering};

const MAX_SEQ: i32 = 9;

static SEQ: AtomicI32 = AtomicI32::new(0);

rt::mutex!(MUTEX0);
rt::mutex!(MUTEX1);
rt::mutex!(MUTEX2);

fn sequence(s: i32) {
    assert_eq!(s, SEQ.load(Ordering::Relaxed), "sequence out of order");
    if SEQ.fetch_add(1, Ordering::Relaxed) == MAX_SEQ {
        rt::exit();
    }
}

fn locker0() {
    rt::task::drop_privilege();
    sequence(3);
    {
        let _guard0 = MUTEX0.lock();
        let guard1 = MUTEX1.lock();
        sequence(5);
        drop(guard1);
    }
    sequence(-1);
}

fn locker1() {
    rt::task::drop_privilege();
    sequence(2);
    let guard1 = MUTEX1.lock();
    rt::task::sleep(20);
    sequence(4);
    let _guard2 = MUTEX2.lock();
    drop(guard1);
    sequence(8);
    rt::task::sleep(20);
    sequence(-1);
}

fn spinner() -> ! {
    rt::task::drop_privilege();
    sequence(1);
    rt::task::sleep(10);
    loop {
        rt::task::yield_now();
    }
}

fn donator() {
    rt::task::drop_privilege();
    sequence(0);
    rt::task::sleep(30);
    {
        let _guard0 = MUTEX0.lock();
        sequence(6);
    }
    sequence(7);
    assert!(
        MUTEX2.timed_lock(10).is_none(),
        "donator timedlock succeeded"
    );
    sequence(9);
}

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

rt::task!(locker0, STACK_SIZE, 3);
rt::task!(locker1, STACK_SIZE, 2);
rt::task!(spinner, STACK_SIZE, 1);
rt::task!(donator, STACK_SIZE, 0);