23 |
|
#include "protocol.h" |
24 |
|
#endif |
25 |
|
|
26 |
+ |
static void _dispatch_queue_cleanup2(void); |
27 |
+ |
|
28 |
|
void |
29 |
|
dummy_function(void) |
30 |
|
{ |
379 |
|
// The first xchg on the tail will tell the enqueueing thread that it |
380 |
|
// is safe to blindly write out to the head pointer. A cmpxchg honors |
381 |
|
// the algorithm. |
382 |
< |
dispatch_atomic_cmpxchg(&dq->dq_items_head, mediator, NULL); |
382 |
> |
(void)dispatch_atomic_cmpxchg(&dq->dq_items_head, mediator, NULL); |
383 |
|
_dispatch_debug("no work on global work queue"); |
384 |
|
return NULL; |
385 |
|
} |
476 |
|
_dispatch_hw_config.cc_max_physical = |
477 |
|
_dispatch_hw_config.cc_max_active; |
478 |
|
#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN) |
479 |
< |
_dispatch_hw_config.cc_max_active = (int)sysconf(_SC_NPROCESSORS_ONLN); |
480 |
< |
if (_dispatch_hw_config.cc_max_active < 0) |
481 |
< |
_dispatch_hw_config.cc_max_active = 1; |
479 |
> |
int ret; |
480 |
> |
|
481 |
> |
ret = (int)sysconf(_SC_NPROCESSORS_ONLN); |
482 |
> |
|
483 |
|
_dispatch_hw_config.cc_max_logical = |
484 |
|
_dispatch_hw_config.cc_max_physical = |
485 |
< |
_dispatch_hw_config.cc_max_active; |
485 |
> |
_dispatch_hw_config.cc_max_active = (ret < 0) ? 1 : ret; |
486 |
|
#else |
487 |
|
#warning "_dispatch_queue_set_width_init: no supported way to query CPU count" |
488 |
|
_dispatch_hw_config.cc_max_logical = |
944 |
|
if (pthread_main_np()) { |
945 |
|
#endif |
946 |
|
_dispatch_program_is_probably_callback_driven = true; |
947 |
+ |
#if defined(__linux__) |
948 |
+ |
// Workaround for a GNU/Linux bug that causes the process to become a |
949 |
+ |
// zombie when the main thread calls pthread_exit(). |
950 |
+ |
void *p = _dispatch_thread_getspecific(dispatch_sema4_key); |
951 |
+ |
if (p) dispatch_release(p); |
952 |
+ |
_dispatch_force_cache_cleanup(); |
953 |
+ |
_dispatch_queue_cleanup2(); |
954 |
+ |
#endif // defined(__linux__) |
955 |
|
pthread_exit(NULL); |
956 |
|
DISPATCH_CRASH("pthread_exit() returned"); |
957 |
|
#if HAVE_PTHREAD_MAIN_NP |
984 |
|
// similar non-POSIX API was called |
985 |
|
// this has to run before the DISPATCH_COCOA_COMPAT below |
986 |
|
if (_dispatch_program_is_probably_callback_driven) { |
987 |
+ |
#if defined(__linux__) |
988 |
+ |
// Use the main thread as the signal handler thread on GNU/Linux |
989 |
+ |
_dispatch_sigsuspend(NULL); |
990 |
+ |
#else |
991 |
|
dispatch_async_f(_dispatch_get_root_queue(0, 0), NULL, _dispatch_sigsuspend); |
992 |
|
sleep(1); // workaround 6778970 |
993 |
+ |
#endif // defined(__linux__) |
994 |
|
} |
995 |
|
|
996 |
|
#if DISPATCH_COCOA_COMPAT |
1187 |
|
#endif |
1188 |
|
|
1189 |
|
for (i = 0; i < DISPATCH_ROOT_QUEUE_COUNT; i++) { |
1174 |
– |
#if HAVE_PTHREAD_WORKQUEUES |
1175 |
– |
r = pthread_workqueue_attr_setqueuepriority_np(&pwq_attr, _dispatch_rootq2wq_pri(i)); |
1176 |
– |
(void)dispatch_assume_zero(r); |
1177 |
– |
r = pthread_workqueue_attr_setovercommit_np(&pwq_attr, i & 1); |
1178 |
– |
(void)dispatch_assume_zero(r); |
1190 |
|
// some software hangs if the non-overcommitting queues do not overcommit when threads block |
1191 |
|
#if 0 |
1192 |
|
if (!(i & 1)) { |
1193 |
|
dispatch_root_queue_contexts[i].dgq_thread_pool_size = _dispatch_hw_config.cc_max_active; |
1194 |
|
} |
1195 |
|
#endif |
1196 |
< |
|
1196 |
> |
#if HAVE_PTHREAD_WORKQUEUES |
1197 |
> |
r = pthread_workqueue_attr_setqueuepriority_np(&pwq_attr, _dispatch_rootq2wq_pri(i)); |
1198 |
> |
(void)dispatch_assume_zero(r); |
1199 |
> |
r = pthread_workqueue_attr_setovercommit_np(&pwq_attr, i & 1); |
1200 |
> |
(void)dispatch_assume_zero(r); |
1201 |
|
r = 0; |
1202 |
|
if (disable_wq || (r = pthread_workqueue_create_np(&_dispatch_root_queue_contexts[i].dgq_kworkqueue, &pwq_attr))) { |
1203 |
|
if (r != ENOTSUP) { |
1216 |
|
ret = sem_init(&_dispatch_thread_mediator[i].dsema_sem, 0, 0); |
1217 |
|
(void)dispatch_assume_zero(ret); |
1218 |
|
#endif |
1219 |
+ |
#if USE_WIN32_SEM |
1220 |
+ |
_dispatch_thread_mediator[i].dsema_handle = CreateSemaphore(NULL, 0, LONG_MAX, NULL); |
1221 |
+ |
dispatch_assume(_dispatch_thread_mediator[i].dsema_handle); |
1222 |
+ |
#endif |
1223 |
|
#if HAVE_PTHREAD_WORKQUEUES |
1224 |
|
} else { |
1225 |
< |
dispatch_assume(_dispatch_root_queue_contexts[i].dgq_kworkqueue); |
1225 |
> |
(void)dispatch_assume(_dispatch_root_queue_contexts[i].dgq_kworkqueue); |
1226 |
|
} |
1227 |
|
#endif |
1228 |
|
} |