@@ -211,7 +211,7 @@ DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
211
211
static bool
212
212
bitmap_is_full (bitmap_t bits )
213
213
{
214
- return (bits == BITMAP_ALL_ONES );
214
+ return atomic_load_explicit (bits , memory_order_relaxed ) == BITMAP_ALL_ONES );
215
215
}
216
216
217
217
#define NO_BITS_WERE_UNSET (UINT_MAX)
@@ -220,7 +220,7 @@ bitmap_is_full(bitmap_t bits)
220
220
// allowed to be set.
221
221
DISPATCH_ALWAYS_INLINE_NDEBUG
222
222
static unsigned int
223
- bitmap_set_first_unset_bit_upto_index (volatile bitmap_t * bitmap ,
223
+ bitmap_set_first_unset_bit_upto_index (bitmap_t * bitmap ,
224
224
unsigned int max_index )
225
225
{
226
226
// No barriers needed in acquire path: the just-allocated
@@ -233,7 +233,7 @@ bitmap_set_first_unset_bit_upto_index(volatile bitmap_t *bitmap,
233
233
234
234
DISPATCH_ALWAYS_INLINE
235
235
static unsigned int
236
- bitmap_set_first_unset_bit (volatile bitmap_t * bitmap )
236
+ bitmap_set_first_unset_bit (bitmap_t * bitmap )
237
237
{
238
238
return bitmap_set_first_unset_bit_upto_index (bitmap , UINT_MAX );
239
239
}
@@ -244,7 +244,7 @@ bitmap_set_first_unset_bit(volatile bitmap_t *bitmap)
244
244
// Return true if this bit was the last in the bitmap, and it is now all zeroes
245
245
DISPATCH_ALWAYS_INLINE_NDEBUG
246
246
static bool
247
- bitmap_clear_bit (volatile bitmap_t * bitmap , unsigned int index ,
247
+ bitmap_clear_bit (bitmap_t * bitmap , unsigned int index ,
248
248
bool exclusively )
249
249
{
250
250
#if DISPATCH_DEBUG
@@ -267,8 +267,8 @@ bitmap_clear_bit(volatile bitmap_t *bitmap, unsigned int index,
267
267
268
268
DISPATCH_ALWAYS_INLINE_NDEBUG
269
269
static void
270
- mark_bitmap_as_full_if_still_full (volatile bitmap_t * supermap ,
271
- unsigned int bitmap_index , volatile bitmap_t * bitmap )
270
+ mark_bitmap_as_full_if_still_full (bitmap_t * supermap ,
271
+ unsigned int bitmap_index , bitmap_t * bitmap )
272
272
{
273
273
#if DISPATCH_DEBUG
274
274
dispatch_assert (bitmap_index < BITMAPS_PER_SUPERMAP );
@@ -321,12 +321,12 @@ alloc_continuation_from_magazine(struct dispatch_magazine_s *magazine)
321
321
unsigned int s , b , index ;
322
322
323
323
for (s = 0 ; s < SUPERMAPS_PER_MAGAZINE ; s ++ ) {
324
- volatile bitmap_t * supermap = supermap_address (magazine , s );
324
+ bitmap_t * supermap = supermap_address (magazine , s );
325
325
if (bitmap_is_full (* supermap )) {
326
326
continue ;
327
327
}
328
328
for (b = 0 ; b < BITMAPS_PER_SUPERMAP ; b ++ ) {
329
- volatile bitmap_t * bitmap = bitmap_address (magazine , s , b );
329
+ bitmap_t * bitmap = bitmap_address (magazine , s , b );
330
330
index = bitmap_set_first_unset_bit (bitmap );
331
331
if (index != NO_BITS_WERE_UNSET ) {
332
332
set_last_found_page (
@@ -530,44 +530,37 @@ _dispatch_alloc_maybe_madvise_page(dispatch_continuation_t c)
530
530
// page can't be madvised; maybe it contains non-continuations
531
531
return ;
532
532
}
533
- // Are all the continuations in this page unallocated?
534
- volatile bitmap_t * page_bitmaps ;
533
+
534
+ bitmap_t * page_bitmaps ;
535
535
get_maps_and_indices_for_continuation ((dispatch_continuation_t )page , NULL ,
536
- NULL , ( bitmap_t * * ) & page_bitmaps , NULL );
536
+ NULL , & page_bitmaps , NULL );
537
537
unsigned int i ;
538
+
539
+ // Try to take ownership of them all, and if it fails, unlock the ones we locked
538
540
for (i = 0 ; i < BITMAPS_PER_PAGE ; i ++ ) {
539
- if (page_bitmaps [i ] != 0 ) {
540
- return ;
541
- }
542
- }
543
- // They are all unallocated, so we could madvise the page. Try to
544
- // take ownership of them all.
545
- int last_locked = 0 ;
546
- do {
547
- if (!os_atomic_cmpxchg (& page_bitmaps [last_locked ], BITMAP_C (0 ),
541
+ if (!os_atomic_cmpxchg (& page_bitmaps [i ], BITMAP_C (0 ),
548
542
BITMAP_ALL_ONES , relaxed )) {
549
543
// We didn't get one; since there is a cont allocated in
550
544
// the page, we can't madvise. Give up and unlock all.
551
- goto unlock ;
545
+ break ;
552
546
}
553
- } while (++ last_locked < (signed )BITMAPS_PER_PAGE );
547
+ }
548
+
549
+ if (i >= BITMAPS_PER_PAGE ) {
554
550
#if DISPATCH_DEBUG
555
- // fprintf(stderr, "%s: madvised page %p for cont %p (next = %p), "
556
- // "[%u+1]=%u bitmaps at %p\n", __func__, page, c, c->do_next,
557
- // last_locked-1, BITMAPS_PER_PAGE, &page_bitmaps[0]);
558
- // Scribble to expose use-after-free bugs
559
- // madvise (syscall) flushes these stores
560
- memset (page , DISPATCH_ALLOCATOR_SCRIBBLE , DISPATCH_ALLOCATOR_PAGE_SIZE );
551
+ // fprintf(stderr, "%s: madvised page %p for cont %p (next = %p), "
552
+ // "[%u+1]=%u bitmaps at %p\n", __func__, page, c, c->do_next,
553
+ // last_locked-1, BITMAPS_PER_PAGE, &page_bitmaps[0]);
554
+ // Scribble to expose use-after-free bugs
555
+ // madvise (syscall) flushes these stores
556
+ memset (page , DISPATCH_ALLOCATOR_SCRIBBLE , DISPATCH_ALLOCATOR_PAGE_SIZE );
561
557
#endif
562
- (void )dispatch_assume_zero (madvise (page , DISPATCH_ALLOCATOR_PAGE_SIZE ,
563
- MADV_FREE ));
564
-
565
- unlock :
566
- while (last_locked > 1 ) {
567
- page_bitmaps [-- last_locked ] = BITMAP_C (0 );
558
+ // madvise the page
559
+ (void )dispatch_assume_zero (madvise (page , DISPATCH_ALLOCATOR_PAGE_SIZE ,
560
+ MADV_FREE ));
568
561
}
569
- if ( last_locked ) {
570
- os_atomic_store (& page_bitmaps [0 ], BITMAP_C (0 ), relaxed );
562
+ while ( i ) {
563
+ os_atomic_store (& page_bitmaps [-- i ], BITMAP_C (0 ), relaxed );
571
564
}
572
565
return ;
573
566
}
0 commit comments