#![no_main]
#![cfg_attr(target_os = "none", no_std)]
rt::mutex!(MUTEX, u32, 0);
const NUM_TASKS: u32 = 3;
const ITERATIONS: u32 = 10000;
fn exit_last() {
rt::sem!(EXIT_SEM, NUM_TASKS as i32 - 1);
if !EXIT_SEM.try_wait() {
assert_eq!(
*MUTEX.try_lock().expect("mutex should be unlocked"),
ITERATIONS * NUM_TASKS,
"the mutex did not contain the expected value"
);
rt::exit();
}
}
fn increment_lock() {
rt::task::drop_privilege();
for _ in 0..ITERATIONS {
*MUTEX.lock() += 1;
}
exit_last();
}
fn increment_trylock() {
rt::task::drop_privilege();
for _ in 0..ITERATIONS {
let mut guard = loop {
if let Some(guard) = MUTEX.try_lock() {
break guard;
} else {
rt::task::sleep(1);
}
};
*guard += 1;
}
exit_last();
}
fn increment_timedlock() {
rt::task::drop_privilege();
for _ in 0..ITERATIONS {
let mut guard = loop {
if let Some(guard) = MUTEX.timed_lock(1) {
break guard;
}
};
*guard += 1;
}
exit_last();
}
fn timeout() {
rt::task::sleep(1000);
panic!("timed out");
}
const STACK_SIZE: usize = rt::stack::MIN * 8;
rt::task!(increment_lock, STACK_SIZE, 1);
rt::task!(increment_trylock, STACK_SIZE, 1);
rt::task!(increment_timedlock, STACK_SIZE, 1);
rt::task!(timeout, STACK_SIZE, 0);