about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-12-09 10:50:45 +0000
committerEric Wong <normalperson@yhbt.net>2013-12-09 10:52:36 +0000
commitf5328d433c588e26a7763266208fe3460ef7ee99 (patch)
tree79944ce7b9de03e957320ed21b299aa5e619e88f
parentfe587418ea7a71f34e5a0f49eb20148e82b9c389 (diff)
downloadcmogstored-f5328d433c588e26a7763266208fe3460ef7ee99.tar.gz
This unfortunate loop burned too much CPU on FreeBSD and caused
shutdown to take too long when using sched_yield.  nanosleep for
10ms instead, hopefully allowing the system to accomplish some
disk I/O and other tasks before we poke it again.

Reported-by: Mikolaj Golub
-rw-r--r--thrpool.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/thrpool.c b/thrpool.c
index 8ed5963..80bf1ff 100644
--- a/thrpool.c
+++ b/thrpool.c
@@ -86,9 +86,18 @@ static void poke(pthread_t thr, int sig)
          * This is an uncommon code path and only triggered when
          * we lower thread counts or shut down
          */
-        while ((err = pthread_kill(thr, sig)) == 0)
-                mog_yield();
-
+        while ((err = pthread_kill(thr, sig)) == 0) {
+                /*
+                 * sleep for 10 ms, sched_yield still burns too much CPU
+                 * on FreeBSD (and likely other OSes) if a thread is waiting
+                 * on disk I/O.
+                 */
+                struct timespec ts = { .tv_sec = 0, .tv_nsec = 10e6 };
+                int rc = nanosleep(&ts, NULL);
+
+                if (rc != 0)
+                        assert(errno != EINVAL && "bug in using nanosleep");
+        }
         assert(err == ESRCH && "pthread_kill() usage bug");
 }