@@ -151,7 +151,7 @@ static struct dispatch_pthread_root_queue_context_s
151
151
struct dispatch_root_queue_context_s {
152
152
union {
153
153
struct {
154
- unsigned int volatile dgq_pending ;
154
+ int volatile dgq_pending ;
155
155
#if HAVE_PTHREAD_WORKQUEUES
156
156
qos_class_t dgq_qos ;
157
157
int dgq_wq_priority , dgq_wq_options ;
@@ -669,6 +669,10 @@ _dispatch_root_queues_init_workq(int *wq_supported)
669
669
}
670
670
#endif // DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK
671
671
qc -> dgq_kworkqueue = pwq ? pwq : (void * )(~0ul );
672
+ // because the fastpath of _dispatch_global_queue_poke didn't
673
+ // know yet that we're using the internal pool implementation
674
+ // we have to undo its setting of dgq_pending
675
+ qc -> dgq_pending = 0 ;
672
676
}
673
677
#if DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK
674
678
if (!disable_wq ) {
@@ -694,13 +698,6 @@ _dispatch_root_queue_init_pthread_pool(dispatch_root_queue_context_t qc,
694
698
thread_pool_size = pool_size ;
695
699
}
696
700
qc -> dgq_thread_pool_size = thread_pool_size ;
697
- if (qc -> dgq_kworkqueue == (void * )(~0ul )) {
698
- // when _dispatch_root_queues_init is invoked from
699
- // _dispatch_global_queue_poke_slow we need to clear
700
- // dgq_pending here because qc->dgq_kworkqueue wasn't
701
- // initialized to (~0ul) when we went through _dispatch_global_queue_poke
702
- qc -> dgq_pending = 0 ;
703
- }
704
701
#if HAVE_PTHREAD_WORKQUEUES
705
702
if (qc -> dgq_qos ) {
706
703
(void )dispatch_assume_zero (pthread_attr_init (& pqc -> dpq_thread_attr ));
@@ -1991,9 +1988,8 @@ _dispatch_pthread_root_queue_create(const char *label, unsigned long flags,
1991
1988
dispatch_pthread_root_queue_context_t pqc ;
1992
1989
dispatch_queue_flags_t dqf = 0 ;
1993
1990
size_t dqs ;
1994
- uint8_t pool_size_u = flags & _DISPATCH_PTHREAD_ROOT_QUEUE_FLAG_POOL_SIZE ?
1991
+ int32_t pool_size = flags & _DISPATCH_PTHREAD_ROOT_QUEUE_FLAG_POOL_SIZE ?
1995
1992
(int8_t )(flags & ~_DISPATCH_PTHREAD_ROOT_QUEUE_FLAG_POOL_SIZE ) : 0 ;
1996
- int32_t pool_size = (int32_t )pool_size_u ;
1997
1993
1998
1994
dqs = sizeof (struct dispatch_queue_s ) - DISPATCH_QUEUE_CACHELINE_PAD ;
1999
1995
dqs = roundup (dqs , _Alignof(struct dispatch_root_queue_context_s ));
@@ -5445,7 +5441,7 @@ _dispatch_worker_thread4(void *context)
5445
5441
dispatch_root_queue_context_t qc = dq -> do_ctxt ;
5446
5442
5447
5443
_dispatch_introspection_thread_add ();
5448
- int pending = ( int ) os_atomic_dec2o (qc , dgq_pending , relaxed );
5444
+ int pending = os_atomic_dec2o (qc , dgq_pending , relaxed );
5449
5445
dispatch_assert (pending >= 0 );
5450
5446
_dispatch_root_queue_drain (dq , _dispatch_get_priority ());
5451
5447
_dispatch_voucher_debug ("root queue clear" , NULL );
@@ -5491,8 +5487,10 @@ _dispatch_worker_thread(void *context)
5491
5487
dispatch_root_queue_context_t qc = dq -> do_ctxt ;
5492
5488
dispatch_pthread_root_queue_context_t pqc = qc -> dgq_ctxt ;
5493
5489
5494
- int pending = (int )os_atomic_dec2o (qc , dgq_pending , relaxed );
5495
- dispatch_assert (pending >= 0 );
5490
+ int pending = os_atomic_dec2o (qc , dgq_pending , relaxed );
5491
+ if (unlikely (pending < 0 )) {
5492
+ DISPATCH_INTERNAL_CRASH (pending , "Pending thread request underflow" );
5493
+ }
5496
5494
5497
5495
if (pqc -> dpq_observer_hooks .queue_will_execute ) {
5498
5496
_dispatch_set_pthread_root_queue_observer_hooks (
0 commit comments