rt 0.19.1

A real-time operating system capable of full preemption
Documentation
static HYDROGEN_BONDED: AtomicU32 = AtomicU32::new(0);
static OXYGEN_BONDED: AtomicU32 = AtomicU32::new(0);
static WATER_FORMED: AtomicU32 = AtomicU32::new(0);

fn make_water() {
    WATER_FORMED.fetch_add(1, Ordering::Relaxed);
}

fn timeout() {
    rt::task::drop_privilege();
    rt::task::sleep(1000);

    let w = WATER_FORMED.load(Ordering::Relaxed);
    let h = HYDROGEN_BONDED.load(Ordering::Relaxed);
    let o = OXYGEN_BONDED.load(Ordering::Relaxed);

    /* The oxygen or hydrogen may not have bonded by the time rt::exit is called
     * after making a water molecule, so allow for o and h to be one molecule's
     * worth below expected value or exactly equal to it. */
    let o_lo = w - 1;
    let o_hi = w;
    let h_lo = (w - 1) * 2;
    let h_hi = w * 2;

    assert!(o >= o_lo, "not enough oxygen was bonded");
    assert!(o <= o_hi, "too much oxygen was bonded");
    assert!(h >= h_lo, "not enough hydrogen was bonded");
    assert!(h <= h_hi, "too much hydrogen was bonded");

    rt::exit();
}

fn oxygen_loop() {
    rt::task::drop_privilege();
    loop {
        oxygen();
        OXYGEN_BONDED.fetch_add(1, Ordering::Relaxed);
    }
}

fn hydrogen_loop() {
    rt::task::drop_privilege();
    loop {
        hydrogen();
        HYDROGEN_BONDED.fetch_add(1, Ordering::Relaxed);
    }
}

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

rt::task!(timeout, STACK_SIZE, 0);
rt::task!(hydrogen_loop, STACK_SIZE, 2);
rt::task!(hydrogen_loop, STACK_SIZE, 2);
rt::task!(oxygen_loop, STACK_SIZE, 1);