3
3
extern crate futures;
4
4
extern crate test;
5
5
6
- use futures:: Async ;
6
+ use futures:: { Async , Poll } ;
7
7
use futures:: executor;
8
8
use futures:: executor:: { Notify , NotifyHandle } ;
9
9
use futures:: sync:: BiLock ;
10
+ use futures:: sync:: BiLockAcquire ;
11
+ use futures:: sync:: BiLockAcquired ;
12
+ use futures:: future:: Future ;
13
+ use futures:: stream:: Stream ;
10
14
11
15
12
16
use test:: Bencher ;
@@ -23,60 +27,95 @@ fn notify_noop() -> NotifyHandle {
23
27
NotifyHandle :: from ( NOOP )
24
28
}
25
29
30
+
31
+ /// Pseudo-stream which simply calls `lock.poll()` on `poll`
32
+ struct LockStream {
33
+ lock : BiLockAcquire < u32 > ,
34
+ }
35
+
36
+ impl LockStream {
37
+ fn new ( lock : BiLock < u32 > ) -> LockStream {
38
+ LockStream {
39
+ lock : lock. lock ( )
40
+ }
41
+ }
42
+
43
+ /// Release a lock after it was acquired in `poll`,
44
+ /// so `poll` could be called again.
45
+ fn release_lock ( & mut self , guard : BiLockAcquired < u32 > ) {
46
+ self . lock = guard. unlock ( ) . lock ( )
47
+ }
48
+ }
49
+
50
+ impl Stream for LockStream {
51
+ type Item = BiLockAcquired < u32 > ;
52
+ type Error = ( ) ;
53
+
54
+ fn poll ( & mut self ) -> Poll < Option < Self :: Item > , Self :: Error > {
55
+ self . lock . poll ( ) . map ( |a| match a {
56
+ Async :: Ready ( a) => Async :: Ready ( Some ( a) ) ,
57
+ Async :: NotReady => Async :: NotReady ,
58
+ } )
59
+ }
60
+ }
61
+
62
+
26
63
#[ bench]
27
64
fn contended ( b : & mut Bencher ) {
28
65
b. iter ( || {
29
- let mut t = BiLock :: new ( 1 ) ;
66
+ let ( x, y) = BiLock :: new ( 1 ) ;
67
+
68
+ let mut x = executor:: spawn ( LockStream :: new ( x) ) ;
69
+ let mut y = executor:: spawn ( LockStream :: new ( y) ) ;
70
+
30
71
for _ in 0 ..1000 {
31
- let ( x, y) = t;
32
- let x_lock = match executor:: spawn ( x. lock ( ) ) . poll_future_notify ( & notify_noop ( ) , 11 ) . unwrap ( ) {
33
- Async :: Ready ( lock) => lock,
34
- Async :: NotReady => panic ! ( ) ,
72
+ let x_guard = match x. poll_stream_notify ( & notify_noop ( ) , 11 ) {
73
+ Ok ( Async :: Ready ( Some ( guard) ) ) => guard,
74
+ _ => panic ! ( ) ,
35
75
} ;
36
76
37
77
// Try poll second lock while first lock still holds the lock
38
- let mut y = executor:: spawn ( y. lock ( ) ) ;
39
- match y. poll_future_notify ( & notify_noop ( ) , 11 ) . unwrap ( ) {
40
- Async :: Ready ( _) => panic ! ( ) ,
41
- Async :: NotReady => ( ) ,
78
+ match y. poll_stream_notify ( & notify_noop ( ) , 11 ) {
79
+ Ok ( Async :: NotReady ) => ( ) ,
80
+ _ => panic ! ( ) ,
42
81
} ;
43
82
44
- let x = x_lock . unlock ( ) ;
83
+ x . get_mut ( ) . release_lock ( x_guard ) ;
45
84
46
- let y_lock = match y. poll_future_notify ( & notify_noop ( ) , 11 ) . unwrap ( ) {
47
- Async :: Ready ( lock ) => lock ,
48
- Async :: NotReady => panic ! ( ) ,
85
+ let y_guard = match y. poll_stream_notify ( & notify_noop ( ) , 11 ) {
86
+ Ok ( Async :: Ready ( Some ( guard ) ) ) => guard ,
87
+ _ => panic ! ( ) ,
49
88
} ;
50
89
51
- let y = y_lock. unlock ( ) ;
52
- t = ( x, y) ;
90
+ y. get_mut ( ) . release_lock ( y_guard) ;
53
91
}
54
- t
92
+ ( x , y )
55
93
} ) ;
56
94
}
57
95
58
96
#[ bench]
59
97
fn lock_unlock ( b : & mut Bencher ) {
60
98
b. iter ( || {
61
- let mut t = BiLock :: new ( 1 ) ;
99
+ let ( x, y) = BiLock :: new ( 1 ) ;
100
+
101
+ let mut x = executor:: spawn ( LockStream :: new ( x) ) ;
102
+ let mut y = executor:: spawn ( LockStream :: new ( y) ) ;
103
+
62
104
for _ in 0 ..1000 {
63
- let ( x, y) = t;
64
- let x_lock = match executor:: spawn ( x. lock ( ) ) . poll_future_notify ( & notify_noop ( ) , 11 ) . unwrap ( ) {
65
- Async :: Ready ( lock) => lock,
66
- Async :: NotReady => panic ! ( ) ,
105
+ let x_guard = match x. poll_stream_notify ( & notify_noop ( ) , 11 ) {
106
+ Ok ( Async :: Ready ( Some ( guard) ) ) => guard,
107
+ _ => panic ! ( ) ,
67
108
} ;
68
109
69
- let x = x_lock . unlock ( ) ;
110
+ x . get_mut ( ) . release_lock ( x_guard ) ;
70
111
71
- let mut y = executor:: spawn ( y. lock ( ) ) ;
72
- let y_lock = match y. poll_future_notify ( & notify_noop ( ) , 11 ) . unwrap ( ) {
73
- Async :: Ready ( lock) => lock,
74
- Async :: NotReady => panic ! ( ) ,
112
+ let y_guard = match y. poll_stream_notify ( & notify_noop ( ) , 11 ) {
113
+ Ok ( Async :: Ready ( Some ( guard) ) ) => guard,
114
+ _ => panic ! ( ) ,
75
115
} ;
76
116
77
- let y = y_lock. unlock ( ) ;
78
- t = ( x, y) ;
117
+ y. get_mut ( ) . release_lock ( y_guard) ;
79
118
}
80
- t
119
+ ( x , y )
81
120
} )
82
121
}
0 commit comments