rt/rust/examples/donate.rs

70 lines
1.4 KiB
Rust

#![no_main]
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::trap();
}
}
fn locker0() {
rt::task::drop_privilege();
sequence(3);
{
let _guard0 = MUTEX0.lock();
let _guard1 = MUTEX1.lock();
sequence(5);
}
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 {}
}
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);
}
rt::task!(locker0, rt::task::STACK_MIN, 3);
rt::task!(locker1, rt::task::STACK_MIN, 2);
rt::task!(spinner, rt::task::STACK_MIN, 1);
rt::task!(donator, rt::task::STACK_MIN, 0);