mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 18:03:25 +00:00
Add unit tests for WaitQueue
and Waiter
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
a664f1a9fc
commit
0bafc0f18a
@ -257,3 +257,120 @@ impl Waker {
|
||||
self.has_woken.store(true, Ordering::Release);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(ktest)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::task::TaskOptions;
|
||||
|
||||
fn queue_wake<F>(wake: F)
|
||||
where
|
||||
F: Fn(&WaitQueue) + Sync + Send + 'static,
|
||||
{
|
||||
let queue = Arc::new(WaitQueue::new());
|
||||
let queue_cloned = queue.clone();
|
||||
|
||||
let cond = Arc::new(AtomicBool::new(false));
|
||||
let cond_cloned = cond.clone();
|
||||
|
||||
TaskOptions::new(move || {
|
||||
Task::yield_now();
|
||||
|
||||
cond_cloned.store(true, Ordering::Relaxed);
|
||||
wake(&*queue_cloned);
|
||||
})
|
||||
.data(())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
queue.wait_until(|| cond.load(Ordering::Relaxed).then_some(()));
|
||||
|
||||
assert!(cond.load(Ordering::Relaxed));
|
||||
}
|
||||
|
||||
#[ktest]
|
||||
fn queue_wake_one() {
|
||||
queue_wake(|queue| {
|
||||
queue.wake_one();
|
||||
});
|
||||
}
|
||||
|
||||
#[ktest]
|
||||
fn queue_wake_all() {
|
||||
queue_wake(|queue| {
|
||||
queue.wake_all();
|
||||
});
|
||||
}
|
||||
|
||||
#[ktest]
|
||||
fn waiter_wake_twice() {
|
||||
let (_waiter, waker) = Waiter::new_pair();
|
||||
|
||||
assert!(waker.wake_up());
|
||||
assert!(!waker.wake_up());
|
||||
}
|
||||
|
||||
#[ktest]
|
||||
fn waiter_wake_drop() {
|
||||
let (waiter, waker) = Waiter::new_pair();
|
||||
|
||||
drop(waiter);
|
||||
assert!(!waker.wake_up());
|
||||
}
|
||||
|
||||
#[ktest]
|
||||
fn waiter_wake_async() {
|
||||
let (waiter, waker) = Waiter::new_pair();
|
||||
|
||||
let cond = Arc::new(AtomicBool::new(false));
|
||||
let cond_cloned = cond.clone();
|
||||
|
||||
TaskOptions::new(move || {
|
||||
Task::yield_now();
|
||||
|
||||
cond_cloned.store(true, Ordering::Relaxed);
|
||||
assert!(waker.wake_up());
|
||||
})
|
||||
.data(())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
waiter.wait();
|
||||
|
||||
assert!(cond.load(Ordering::Relaxed));
|
||||
}
|
||||
|
||||
#[ktest]
|
||||
fn waiter_wake_reorder() {
|
||||
let (waiter, waker) = Waiter::new_pair();
|
||||
|
||||
let cond = Arc::new(AtomicBool::new(false));
|
||||
let cond_cloned = cond.clone();
|
||||
|
||||
let (waiter2, waker2) = Waiter::new_pair();
|
||||
|
||||
let cond2 = Arc::new(AtomicBool::new(false));
|
||||
let cond2_cloned = cond2.clone();
|
||||
|
||||
TaskOptions::new(move || {
|
||||
Task::yield_now();
|
||||
|
||||
cond2_cloned.store(true, Ordering::Relaxed);
|
||||
assert!(waker2.wake_up());
|
||||
|
||||
Task::yield_now();
|
||||
|
||||
cond_cloned.store(true, Ordering::Relaxed);
|
||||
assert!(waker.wake_up());
|
||||
})
|
||||
.data(())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
waiter.wait();
|
||||
assert!(cond.load(Ordering::Relaxed));
|
||||
|
||||
waiter2.wait();
|
||||
assert!(cond2.load(Ordering::Relaxed));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user