diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-06-21 03:34:35 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-06-25 22:07:40 +0000 |
commit | a18a08a0e9a7c472656afc86cbbbfcefda5e456d (patch) | |
tree | 614430dacaeadb9ae13ea65097c46b76043653b7 /thrpool.c | |
parent | df9729555394542064d1c9e9d1b67446bf36d3f3 (diff) | |
download | cmogstored-a18a08a0e9a7c472656afc86cbbbfcefda5e456d.tar.gz |
This should allow the threads we're terminating to more quickly enter a safe state where they're allowed to exit. On SMP systems, we need to yield the signalling thread more times to increase the probability the interrupted thread can run (and exit).
Diffstat (limited to 'thrpool.c')
-rw-r--r-- | thrpool.c | 22 |
1 files changed, 20 insertions, 2 deletions
@@ -67,6 +67,24 @@ void mog_thr_test_quit(void) } /* + * sched_yield may migrate us to the same CPU as the task we're waiting + * on, so just keep yielding for every CPU we have as this throttles + * our ability to spam SIGURG. This means the threads we're trying to + * gracefully kill off can finish their work and check their mog_do_quit + * flag sooner + */ +static void yield_all(void) +{ + static unsigned long nproc_all; + unsigned long i; + + if (!nproc_all) + nproc_all = num_processors(NPROC_ALL) * 2; + for (i = 0; i < nproc_all; i++) + pthread_yield(); +} + +/* * we no longer rely on pthreads cancellation, so our explicit checks for * thread quitting requires us to continuously signal a thread for death * in case it enters a sleeping syscall (epoll_wait/kevent) immediately @@ -81,7 +99,7 @@ static void poke(pthread_t thr, int sig) * we lower thread counts or shut down */ while ((err = pthread_kill(thr, sig)) == 0) - sched_yield(); + yield_all(); assert(err == ESRCH && "pthread_kill() usage bug"); } @@ -97,7 +115,7 @@ thr_create_fail_retry(struct mog_thrpool *tp, size_t size, syslog(LOG_ERR, "pthread_create: %m (tries: %lu)", *nr_eagain); } - sched_yield(); + yield_all(); return true; } else { errno = err; |