aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarat Dukhan <maratek@google.com>2019-09-30 14:22:45 -0700
committerMarat Dukhan <maratek@google.com>2019-09-30 14:22:45 -0700
commitafb23f9ac963caaea7685a3d454e80b80417ddec (patch)
tree60432cfb6062b06f3ed49a073bcfd68cd23ad156
parente807f76c98bfde48b242607bbb76ccd1ec903948 (diff)
downloadplatform_external_pthreadpool-afb23f9ac963caaea7685a3d454e80b80417ddec.tar.gz
platform_external_pthreadpool-afb23f9ac963caaea7685a3d454e80b80417ddec.tar.bz2
platform_external_pthreadpool-afb23f9ac963caaea7685a3d454e80b80417ddec.zip
Enable spin-wait in worker threads
-rw-r--r--src/threadpool-pthreads.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/src/threadpool-pthreads.c b/src/threadpool-pthreads.c
index 8fffd0b..ea6d6ae 100644
--- a/src/threadpool-pthreads.c
+++ b/src/threadpool-pthreads.c
@@ -34,6 +34,9 @@
/* Library header */
#include <pthreadpool.h>
+/* Number of iterations in spin-wait loop before going into futex/mutex wait */
+#define PTHREADPOOL_SPIN_WAIT_ITERATIONS 1000000
+
#define PTHREADPOOL_CACHELINE_SIZE 64
#define PTHREADPOOL_CACHELINE_ALIGNED __attribute__((__aligned__(PTHREADPOOL_CACHELINE_SIZE)))
@@ -286,30 +289,52 @@ static void thread_compute_1d(struct pthreadpool* threadpool, struct thread_info
}
}
-static uint32_t wait_for_new_command(
+static uint32_t spin_wait_for_new_command(
struct pthreadpool* threadpool,
uint32_t last_command)
{
- #if PTHREADPOOL_USE_FUTEX
- uint32_t command;
- while ((command = threadpool->command) == last_command) {
- futex_wait(&threadpool->command, last_command);
- }
+ uint32_t command = threadpool->command;
+ if (command != last_command) {
+ __sync_synchronize();
return command;
- #else
- /* Lock the command mutex */
- pthread_mutex_lock(&threadpool->command_mutex);
- /* Read the command */
- uint32_t command;
- while ((command = threadpool->command) == last_command) {
- /* Wait for new command */
- pthread_cond_wait(&threadpool->command_condvar, &threadpool->command_mutex);
+ }
+ for (uint32_t i = 0; i < PTHREADPOOL_SPIN_WAIT_ITERATIONS; i++) {
+ __sync_synchronize();
+ command = threadpool->command;
+ if (command != last_command) {
+ __sync_synchronize();
+ return command;
}
- /* Read a new command */
- pthread_mutex_unlock(&threadpool->command_mutex);
+ }
+ return last_command;
+}
- return command;
- #endif
+static uint32_t wait_for_new_command(
+ struct pthreadpool* threadpool,
+ uint32_t last_command)
+{
+ uint32_t command = spin_wait_for_new_command(threadpool, last_command);
+ if (command == last_command) {
+ /* Spin-wait timed out, fall back to mutex/futex wait */
+ #if PTHREADPOOL_USE_FUTEX
+ do {
+ futex_wait(&threadpool->command, last_command);
+ command = threadpool->command;
+ } while (command == last_command);
+ #else
+ /* Lock the command mutex */
+ pthread_mutex_lock(&threadpool->command_mutex);
+ /* Read the command */
+ while ((command = threadpool->command) == last_command) {
+ /* Wait for new command */
+ pthread_cond_wait(&threadpool->command_condvar, &threadpool->command_mutex);
+ }
+ /* Read a new command */
+ pthread_mutex_unlock(&threadpool->command_mutex);
+ #endif
+ __sync_synchronize();
+ }
+ return command;
}
static void* thread_main(void* arg) {