Skip to content

Commit df79882

Browse files
committed
tests: restore disabled tests and benches for BiLock
1 parent d2d1d5e commit df79882

File tree

4 files changed

+176
-224
lines changed

4 files changed

+176
-224
lines changed

futures-util/benches/bilock.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#![feature(test)]
2+
3+
extern crate test;
4+
5+
#[cfg(feature = "bilock")]
6+
mod bench {
7+
use futures::task::Poll;
8+
use futures_test::task::noop_context;
9+
use futures_util::lock::BiLock;
10+
11+
use crate::test::Bencher;
12+
13+
#[bench]
14+
fn contended(b: &mut Bencher) {
15+
let mut context = noop_context();
16+
17+
b.iter(|| {
18+
let (x, y) = BiLock::new(1);
19+
20+
for _ in 0..1000 {
21+
let x_guard = match x.poll_lock(&mut context) {
22+
Poll::Ready(guard) => guard,
23+
_ => panic!(),
24+
};
25+
26+
// Try poll second lock while first lock still holds the lock
27+
match y.poll_lock(&mut context) {
28+
Poll::Pending => (),
29+
_ => panic!(),
30+
};
31+
32+
drop(x_guard);
33+
34+
let y_guard = match y.poll_lock(&mut context) {
35+
Poll::Ready(guard) => guard,
36+
_ => panic!(),
37+
};
38+
39+
drop(y_guard);
40+
}
41+
(x, y)
42+
});
43+
}
44+
45+
#[bench]
46+
fn lock_unlock(b: &mut Bencher) {
47+
let mut context = noop_context();
48+
49+
b.iter(|| {
50+
let (x, y) = BiLock::new(1);
51+
52+
for _ in 0..1000 {
53+
let x_guard = match x.poll_lock(&mut context) {
54+
Poll::Ready(guard) => guard,
55+
_ => panic!(),
56+
};
57+
58+
drop(x_guard);
59+
60+
let y_guard = match y.poll_lock(&mut context) {
61+
Poll::Ready(guard) => guard,
62+
_ => panic!(),
63+
};
64+
65+
drop(y_guard);
66+
}
67+
(x, y)
68+
})
69+
}
70+
}

futures-util/benches_disabled/bilock.rs

Lines changed: 0 additions & 122 deletions
This file was deleted.

futures/tests/bilock.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#[cfg(feature = "bilock")]
2+
mod tests {
3+
use futures::executor::block_on;
4+
use futures::future;
5+
use futures::stream;
6+
use futures::task::{Context, Poll};
7+
use futures::Future;
8+
use futures::StreamExt;
9+
use futures_test::task::noop_context;
10+
use futures_util::lock::BiLock;
11+
use std::pin::Pin;
12+
use std::thread;
13+
14+
#[test]
15+
fn smoke() {
16+
let future = future::lazy(|cx| {
17+
18+
let (a, b) = BiLock::new(1);
19+
20+
{
21+
let mut lock = match a.poll_lock(cx) {
22+
Poll::Ready(l) => l,
23+
Poll::Pending => panic!("poll not ready"),
24+
};
25+
assert_eq!(*lock, 1);
26+
*lock = 2;
27+
28+
assert!(b.poll_lock(cx).is_pending());
29+
assert!(a.poll_lock(cx).is_pending());
30+
}
31+
32+
assert!(b.poll_lock(cx).is_ready());
33+
assert!(a.poll_lock(cx).is_ready());
34+
35+
{
36+
let lock = match b.poll_lock(cx) {
37+
Poll::Ready(l) => l,
38+
Poll::Pending => panic!("poll not ready"),
39+
};
40+
assert_eq!(*lock, 2);
41+
}
42+
43+
assert_eq!(a.reunite(b).expect("bilock/smoke: reunite error"), 2);
44+
45+
Ok::<(), ()>(())
46+
});
47+
48+
assert_eq!(block_on(future), Ok(()));
49+
}
50+
51+
#[test]
52+
fn concurrent() {
53+
const N: usize = 10000;
54+
let mut cx = noop_context();
55+
let (a, b) = BiLock::new(0);
56+
57+
let a = Increment { a: Some(a), remaining: N };
58+
let b = stream::iter(0..N).fold(b, |b, _n| async {
59+
let mut g = b.lock().await;
60+
*g += 1;
61+
drop(g);
62+
b
63+
});
64+
65+
let t1 = thread::spawn(move || block_on(a));
66+
let b = block_on(b);
67+
let a = t1.join().unwrap();
68+
69+
match a.poll_lock(&mut cx) {
70+
Poll::Ready(l) => assert_eq!(*l, 2 * N),
71+
Poll::Pending => panic!("poll not ready"),
72+
}
73+
match b.poll_lock(&mut cx) {
74+
Poll::Ready(l) => assert_eq!(*l, 2 * N),
75+
Poll::Pending => panic!("poll not ready"),
76+
}
77+
78+
assert_eq!(a.reunite(b).expect("bilock/concurrent: reunite error"), 2 * N);
79+
80+
struct Increment {
81+
remaining: usize,
82+
a: Option<BiLock<usize>>,
83+
}
84+
85+
impl Future for Increment {
86+
type Output = BiLock<usize>;
87+
88+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<BiLock<usize>> {
89+
loop {
90+
if self.remaining == 0 {
91+
return self.a.take().unwrap().into();
92+
}
93+
94+
let a = self.a.as_mut().unwrap();
95+
let mut a = match a.poll_lock(cx) {
96+
Poll::Ready(l) => l,
97+
Poll::Pending => return Poll::Pending,
98+
};
99+
*a += 1;
100+
drop(a);
101+
self.remaining -= 1;
102+
}
103+
}
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)