#![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::trap(); } } 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);