74 lines
1.4 KiB
Rust
74 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);
|
|
if MUTEX2.timed_lock(10).is_none() {
|
|
sequence(9);
|
|
}
|
|
}
|
|
|
|
fn timeout() {
|
|
rt::task::sleep(100);
|
|
panic!("timed out");
|
|
}
|
|
|
|
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);
|