76 lines
1.6 KiB
Rust
76 lines
1.6 KiB
Rust
use core::sync::atomic::{AtomicBool, Ordering};
|
|
|
|
rt::mutex!(MUTEX, u32, 0);
|
|
|
|
const NUM_TASKS: u32 = 3;
|
|
const ITERATIONS: u32 = 10000;
|
|
|
|
fn stop_last() {
|
|
rt::semaphore!(STOP_SEM, NUM_TASKS as i32 - 1);
|
|
if !STOP_SEM.try_wait() {
|
|
rt::stop();
|
|
}
|
|
}
|
|
|
|
fn increment_lock() {
|
|
rt::task::drop_privilege();
|
|
for _ in 0..ITERATIONS {
|
|
*MUTEX.lock() += 1;
|
|
}
|
|
stop_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;
|
|
}
|
|
stop_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;
|
|
}
|
|
stop_last();
|
|
}
|
|
|
|
static TIMED_OUT: AtomicBool = AtomicBool::new(false);
|
|
|
|
fn timeout() {
|
|
rt::task::sleep(1000);
|
|
TIMED_OUT.store(true, Ordering::Relaxed);
|
|
rt::stop();
|
|
}
|
|
|
|
fn main() {
|
|
rt::task!(increment_lock, rt::task::STACK_MIN, 1);
|
|
rt::task!(increment_trylock, rt::task::STACK_MIN, 1);
|
|
rt::task!(increment_timedlock, rt::task::STACK_MIN, 1);
|
|
rt::task!(timeout, rt::task::STACK_MIN, 2);
|
|
rt::start();
|
|
|
|
if TIMED_OUT.load(Ordering::Relaxed) {
|
|
panic!("timed out");
|
|
}
|
|
|
|
let guard = MUTEX.try_lock().expect("mutex should be unlocked");
|
|
|
|
if *guard != ITERATIONS * NUM_TASKS {
|
|
panic!("the mutex did not contain the expected value");
|
|
}
|
|
}
|