use super::*;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
const RELOAD: u32 = 1000;
const TEST_DURATION_MS: u64 = 2000;
#[test]
fn monotonicity_stress_test() {
let timer = Arc::new(Mutex::new(Timer::new(1_000_000, RELOAD, 48_000_000)));
timer.lock().unwrap().set_syst(RELOAD);
let stop_signal = Arc::new(AtomicBool::new(false));
let timer_hw = timer.clone();
let stop_hw = stop_signal.clone();
let hw_thread = thread::spawn(move || {
while !stop_hw.load(Ordering::Relaxed) {
let timer_guard = timer_hw.lock().unwrap();
let current_val = timer_guard.get_syst();
if current_val > 0 {
timer_guard.set_syst(current_val - 1);
} else {
timer_guard.set_syst(RELOAD);
timer_guard.set_pendst_pending(true);
}
drop(timer_guard);
thread::sleep(Duration::from_nanos(100));
}
});
let timer_isr = timer.clone();
let stop_isr = stop_signal.clone();
let isr_thread = thread::spawn(move || {
while !stop_isr.load(Ordering::Relaxed) {
let timer_guard = timer_isr.lock().unwrap();
if timer_guard.is_systick_pending_internal() {
timer_guard.set_pendst_pending(false); timer_guard.systick_handler();
}
drop(timer_guard);
thread::sleep(Duration::from_micros(1));
}
});
let timer_app = timer.clone();
let stop_app = stop_signal.clone();
let app_thread = thread::spawn(move || {
let mut last_seen_time = 0;
let mut iterations = 0;
while !stop_app.load(Ordering::Relaxed) {
let current_time = timer_app.lock().unwrap().now();
assert!(
current_time >= last_seen_time,
"Monotonicity failed! current: {}, last: {}",
current_time,
last_seen_time
);
last_seen_time = current_time;
iterations += 1;
}
println!("Checker thread completed {} iterations.", iterations);
});
println!("Running stress test for {}ms...", TEST_DURATION_MS);
thread::sleep(Duration::from_millis(TEST_DURATION_MS));
stop_signal.store(true, Ordering::Relaxed);
hw_thread.join().unwrap();
isr_thread.join().unwrap();
app_thread.join().unwrap();
println!("Stress test passed.");
}