rt/rust/examples/donate.rs

92 lines
1.9 KiB
Rust

use core::sync::atomic::{AtomicBool, AtomicI32, Ordering};
const MAX_SEQ: i32 = 9;
static SEQ: AtomicI32 = AtomicI32::new(0);
static OUT_OF_ORDER: AtomicBool = AtomicBool::new(false);
rt::mutex!(MUTEX0);
rt::mutex!(MUTEX1);
rt::mutex!(MUTEX2);
fn sequence(s: i32) {
if SEQ.load(Ordering::Relaxed) == s {
SEQ.fetch_add(1, Ordering::Relaxed);
} else {
OUT_OF_ORDER.store(true, Ordering::Relaxed);
}
if OUT_OF_ORDER.load(Ordering::Relaxed) || (SEQ.load(Ordering::Relaxed) > MAX_SEQ) {
rt::stop();
}
}
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);
if MUTEX2.timed_lock(10).is_none() {
sequence(9);
}
}
static TIMED_OUT: AtomicBool = AtomicBool::new(false);
fn timeout() {
rt::task::sleep(100);
TIMED_OUT.store(true, Ordering::Relaxed);
rt::stop();
}
fn main() {
rt::task!(locker0, rt::task::STACK_MIN, 1);
rt::task!(locker1, rt::task::STACK_MIN, 2);
rt::task!(spinner, rt::task::STACK_MIN, 3);
rt::task!(donator, rt::task::STACK_MIN, 4);
rt::task!(timeout, rt::task::STACK_MIN, 5);
rt::start();
if TIMED_OUT.load(Ordering::Relaxed) {
panic!("timed out");
}
if OUT_OF_ORDER.load(Ordering::Relaxed) {
panic!("out of order");
}
}