rt/rust/examples/mutex.rs

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");
}
}