@@ -19,6 +19,7 @@ use crate::loom::cell::UnsafeCell;
19
19
use crate :: loom:: sync:: atomic:: AtomicUsize ;
20
20
use crate :: loom:: sync:: { Mutex , MutexGuard } ;
21
21
use crate :: util:: linked_list:: { self , LinkedList } ;
22
+ use crate :: util:: WakeList ;
22
23
23
24
use std:: future:: Future ;
24
25
use std:: marker:: PhantomPinned ;
@@ -239,12 +240,12 @@ impl Semaphore {
239
240
/// If `rem` exceeds the number of permits needed by the wait list, the
240
241
/// remainder are assigned back to the semaphore.
241
242
fn add_permits_locked ( & self , mut rem : usize , waiters : MutexGuard < ' _ , Waitlist > ) {
242
- let mut wakers: [ Option < Waker > ; 8 ] = Default :: default ( ) ;
243
+ let mut wakers = WakeList :: new ( ) ;
243
244
let mut lock = Some ( waiters) ;
244
245
let mut is_empty = false ;
245
246
while rem > 0 {
246
247
let mut waiters = lock. take ( ) . unwrap_or_else ( || self . waiters . lock ( ) ) ;
247
- ' inner: for slot in & mut wakers[ .. ] {
248
+ ' inner: while wakers. can_push ( ) {
248
249
// Was the waiter assigned enough permits to wake it?
249
250
match waiters. queue . last ( ) {
250
251
Some ( waiter) => {
@@ -260,7 +261,11 @@ impl Semaphore {
260
261
}
261
262
} ;
262
263
let mut waiter = waiters. queue . pop_back ( ) . unwrap ( ) ;
263
- * slot = unsafe { waiter. as_mut ( ) . waker . with_mut ( |waker| ( * waker) . take ( ) ) } ;
264
+ if let Some ( waker) =
265
+ unsafe { waiter. as_mut ( ) . waker . with_mut ( |waker| ( * waker) . take ( ) ) }
266
+ {
267
+ wakers. push ( waker) ;
268
+ }
264
269
}
265
270
266
271
if rem > 0 && is_empty {
@@ -283,10 +288,7 @@ impl Semaphore {
283
288
284
289
drop ( waiters) ; // release the lock
285
290
286
- wakers
287
- . iter_mut ( )
288
- . filter_map ( Option :: take)
289
- . for_each ( Waker :: wake) ;
291
+ wakers. wake_all ( ) ;
290
292
}
291
293
292
294
assert_eq ! ( rem, 0 ) ;
0 commit comments