use std::sync::{Arc, Barrier};
use crate::spinlock::SpinLock;
use crate::test_utils;
#[test]
fn cycle() {
let lock = SpinLock::new(0);
let mut guard_1 = lock.lock();
assert_eq!(0, *guard_1);
*guard_1 = 42;
let guard_2 = lock.try_lock();
assert!(guard_2.is_none());
drop(guard_1);
let mut guard_3 = lock.try_lock().unwrap();
assert_eq!(42, *guard_3);
*guard_3 = 69;
assert_eq!(69, *guard_3);
drop(guard_3);
}
#[test]
fn borrow_mut() {
let mut lock = SpinLock::new(0);
let val = lock.get_mut();
*val = 42;
let guard = lock.lock();
assert_eq!(42, *guard);
}
#[test]
fn into_inner() {
let lock = SpinLock::new(0);
let mut guard = lock.lock();
assert_eq!(0, *guard);
*guard = 42;
drop(guard);
assert_eq!(42, lock.into_inner());
}
#[test]
fn await_release() {
for _ in 0..10 {
let lock = Arc::new(SpinLock::new(0));
let mut guard_1 = lock.lock();
*guard_1 = 42;
let t_2_before_acquire = Arc::new(Barrier::new(2));
let t_2_acquired = Arc::new(Barrier::new(2));
let t_2 = {
let lock = lock.clone();
let t_2_before_acquire = t_2_before_acquire.clone();
let t_2_acquired = t_2_acquired.clone();
test_utils::spawn_blocked(move || {
assert!(lock.try_lock().is_none());
t_2_before_acquire.wait();
let mut guard_2 = lock.lock();
t_2_acquired.wait();
assert_eq!(42, *guard_2);
*guard_2 = 69;
})
};
assert!(!t_2.is_finished());
assert_eq!(42, *guard_1);
t_2_before_acquire.wait();
drop(guard_1);
t_2_acquired.wait();
let guard_3 = lock.lock();
assert_eq!(69, *guard_3);
}
}
#[test]
fn debug() {
let lock = SpinLock::new(5);
println!("{:?}", lock);
assert!(format!("{:?}", lock).contains("SpinLock"));
assert!(format!("{:?}", lock).contains("5"));
let guard = lock.lock();
println!("{:?}", lock);
assert!(format!("{:?}", lock).contains("<locked>"));
drop(guard);
}