@@ -51,7 +51,7 @@ static volatile int32_t _dispatch_workq_runnable_workers;
51
51
* The desired number of runnable worker threads
52
52
* for a workqueue (assuming sufficient work).
53
53
*/
54
- static int _dispatch_workq_target_runnable_workers ;
54
+ static int32_t _dispatch_workq_target_runnable_workers ;
55
55
56
56
#if DISPATCH_ENABLE_PWQ_KEXT
57
57
/* Are we using user-level or kext based management? */
@@ -63,10 +63,10 @@ static bool _dispatch_workq_kext_active;
63
63
*/
64
64
typedef struct dispatch_workq_manager_s {
65
65
/*
66
- * Tracking of registered workers; all updates and reads are performed
67
- * holding the mutex .
66
+ * Tracking of registered workers; all updates and reads
67
+ * are performed while holding the lock .
68
68
*/
69
- pthread_mutex_t registered_worker_mutex ;
69
+ dispatch_unfair_lock_s registered_worker_lock ;
70
70
int num_registered_workers ;
71
71
pid_t * registered_workers ;
72
72
@@ -116,17 +116,15 @@ dispatch_workq_worker_register(dispatch_queue_t root_q)
116
116
#endif
117
117
bool rc ;
118
118
int tid = syscall (SYS_gettid );
119
- int r = pthread_mutex_lock (& _dispatch_workq_manager .registered_worker_mutex );
120
- (void )dispatch_assume_zero (r );
119
+ _dispatch_unfair_lock_lock (& _dispatch_workq_manager .registered_worker_lock );
121
120
if (_dispatch_workq_manager .num_registered_workers < WORKQ_MAX_TRACKED_WORKERS - 1 ) {
122
121
int worker_id = _dispatch_workq_manager .num_registered_workers ++ ;
123
122
_dispatch_workq_manager .registered_workers [worker_id ] = tid ;
124
123
rc = true;
125
124
} else {
126
125
rc = false;
127
126
}
128
- r = pthread_mutex_unlock (& _dispatch_workq_manager .registered_worker_mutex );
129
- (void )dispatch_assume_zero (r );
127
+ _dispatch_unfair_lock_unlock (& _dispatch_workq_manager .registered_worker_lock );
130
128
131
129
return rc ;
132
130
}
@@ -146,8 +144,7 @@ dispatch_workq_worker_unregister(dispatch_queue_t root_q)
146
144
}
147
145
#endif
148
146
int tid = syscall (SYS_gettid );
149
- int r = pthread_mutex_lock (& _dispatch_workq_manager .registered_worker_mutex );
150
- (void )dispatch_assume_zero (r );
147
+ _dispatch_unfair_lock_lock (& _dispatch_workq_manager .registered_worker_lock );
151
148
for (int i = 0 ; i < _dispatch_workq_manager .num_registered_workers ; i ++ ) {
152
149
if (_dispatch_workq_manager .registered_workers [i ] == tid ) {
153
150
int last = _dispatch_workq_manager .num_registered_workers - 1 ;
@@ -157,8 +154,7 @@ dispatch_workq_worker_unregister(dispatch_queue_t root_q)
157
154
break ;
158
155
}
159
156
}
160
- r = pthread_mutex_unlock (& _dispatch_workq_manager .registered_worker_mutex );
161
- (void )dispatch_assume_zero (r );
157
+ _dispatch_unfair_lock_unlock (& _dispatch_workq_manager .registered_worker_lock );
162
158
}
163
159
164
160
@@ -173,26 +169,24 @@ _dispatch_workq_count_runnable_workers(void)
173
169
char path [128 ];
174
170
char buf [4096 ];
175
171
int running_count = 0 ;
176
- int r ;
177
172
178
173
memset (buf , 0 , sizeof (buf ));
179
174
180
- r = pthread_mutex_lock (& _dispatch_workq_manager .registered_worker_mutex );
181
- (void )dispatch_assume_zero (r );
175
+ _dispatch_unfair_lock_lock (& _dispatch_workq_manager .registered_worker_lock );
182
176
183
177
for (int i = 0 ; i < _dispatch_workq_manager .num_registered_workers ; i ++ ) {
184
178
pid_t worker_pid = _dispatch_workq_manager .registered_workers [i ];
185
179
int fd ;
186
180
size_t bytes_read = -1 ;
187
181
188
- r = snprintf (path , sizeof (path ), "/proc/%d/stat" , worker_pid );
182
+ int r = snprintf (path , sizeof (path ), "/proc/%d/stat" , worker_pid );
189
183
(void )dispatch_assume (r > 0 && r < sizeof (path ));
190
184
191
185
fd = open (path , O_RDONLY | O_NONBLOCK );
192
186
if (unlikely (fd == -1 )) {
193
187
// Unable to open file.
194
188
// Must mean worker exited uncleanly (without executing _dispatch_worker_unregister())
195
- // Clean up by removing pid and decrementing number of workers in pool
189
+ // Clean up by removing pid and decrementing number of registered workers
196
190
_dispatch_debug ("workq: Unable to open /proc/%d/stat; removing worker from monitoring list" , worker_pid );
197
191
int last = _dispatch_workq_manager .num_registered_workers - 1 ;
198
192
_dispatch_workq_manager .registered_workers [i ] = _dispatch_workq_manager .registered_workers [last ];
@@ -219,8 +213,7 @@ _dispatch_workq_count_runnable_workers(void)
219
213
}
220
214
}
221
215
222
- r = pthread_mutex_unlock (& _dispatch_workq_manager .registered_worker_mutex );
223
- (void )dispatch_assume_zero (r );
216
+ _dispatch_unfair_lock_unlock (& _dispatch_workq_manager .registered_worker_lock );
224
217
225
218
return running_count ;
226
219
}
@@ -264,11 +257,6 @@ _dispatch_workq_init_once(void *context DISPATCH_UNUSED)
264
257
return ;
265
258
}
266
259
#endif
267
- int r ;
268
-
269
- r = pthread_mutex_init (& _dispatch_workq_manager .registered_worker_mutex , NULL );
270
- (void )dispatch_assume_zero (r );
271
-
272
260
_dispatch_workq_manager .registered_workers =
273
261
_dispatch_calloc (WORKQ_MAX_TRACKED_WORKERS , sizeof (pid_t ));
274
262
0 commit comments