|
|
- commit ece550d98e1c10017fb91ecfa0d19ae9d2dc45da
- Author: Willy Tarreau <w@1wt.eu>
- Date: Wed Aug 1 19:12:20 2018 +0200
-
- MINOR: threads: add more consistency between certain variables in no-thread case
-
- When threads are disabled, some variables such as tid and tid_bit are
- still checked everywhere, the MAX_THREADS_MASK macro is ~0UL while
- MAX_THREADS is 1, and the all_threads_mask variable is replaced with a
- macro forced to zero. The compiler cannot optimize away all this code
- involving checks on tid and tid_bit, and we end up in special cases
- where all_threads_mask has to be specifically tested for being zero or
- not. It is not even certain the code paths are always equivalent when
- testing without threads and with nbthread 1.
-
- Let's change this to make sure we always present a single thread when
- threads are disabled, and have the relevant values declared as constants
- so that the compiler can optimize all the tests away. Now we have
- MAX_THREADS_MASK set to 1, all_threads_mask set to 1, tid set to zero
- and tid_bit set to 1. Doing just this has removed 4 kB of code in the
- no-thread case.
-
- A few checks for all_threads_mask==0 have been removed since it never
- happens anymore.
-
- (cherry picked from commit 0c026f49e7348bce5b3c74be896ae208ae6e26a4)
- [wt: the thread code feels safer with this, especially with the small updates
- needed for the rdv point; missed one occurrence fixed by next patch]
- Signed-off-by: Willy Tarreau <w@1wt.eu>
-
- diff --git a/include/common/hathreads.h b/include/common/hathreads.h
- index 4e72848e..7eb5d127 100644
- --- a/include/common/hathreads.h
- +++ b/include/common/hathreads.h
- @@ -24,10 +24,6 @@
-
- #include <common/config.h>
-
- -#define MAX_THREADS_MASK ((unsigned long)-1)
- -extern THREAD_LOCAL unsigned int tid; /* The thread id */
- -extern THREAD_LOCAL unsigned long tid_bit; /* The bit corresponding to the thread id */
- -
- /* Note about all_threads_mask :
- * - with threads support disabled, this symbol is defined as zero (0UL).
- * - with threads enabled, this variable is never zero, it contains the mask
- @@ -37,7 +33,14 @@ extern THREAD_LOCAL unsigned long tid_bit; /* The bit corresponding to the threa
- #ifndef USE_THREAD
-
- #define MAX_THREADS 1
- -#define all_threads_mask 0UL
- +#define MAX_THREADS_MASK 1
- +
- +/* Only way found to replace variables with constants that are optimized away
- + * at build time.
- + */
- +enum { all_threads_mask = 1UL };
- +enum { tid_bit = 1UL };
- +enum { tid = 0 };
-
- #define __decl_hathreads(decl)
-
- @@ -98,6 +101,9 @@ extern THREAD_LOCAL unsigned long tid_bit; /* The bit corresponding to the threa
-
- #define ha_sigmask(how, set, oldset) sigprocmask(how, set, oldset)
-
- +static inline void ha_set_tid(unsigned int tid)
- +{
- +}
-
- static inline void __ha_barrier_load(void)
- {
- @@ -120,6 +126,7 @@ static inline void __ha_barrier_full(void)
- #include <import/plock.h>
-
- #define MAX_THREADS LONGBITS
- +#define MAX_THREADS_MASK ((unsigned long)-1)
-
- #define __decl_hathreads(decl) decl
-
- @@ -223,10 +230,19 @@ void thread_exit_sync(void);
- int thread_no_sync(void);
- int thread_need_sync(void);
-
- +extern THREAD_LOCAL unsigned int tid; /* The thread id */
- +extern THREAD_LOCAL unsigned long tid_bit; /* The bit corresponding to the thread id */
- extern volatile unsigned long all_threads_mask;
-
- #define ha_sigmask(how, set, oldset) pthread_sigmask(how, set, oldset)
-
- +/* sets the thread ID and the TID bit for the current thread */
- +static inline void ha_set_tid(unsigned int data)
- +{
- + tid = data;
- + tid_bit = (1UL << tid);
- +}
- +
-
- #if defined(DEBUG_THREAD) || defined(DEBUG_FULL)
-
- diff --git a/src/cfgparse.c b/src/cfgparse.c
- index 24349a59..d1474d4b 100644
- --- a/src/cfgparse.c
- +++ b/src/cfgparse.c
- @@ -7652,11 +7652,11 @@ int check_config_validity()
- nbproc = my_ffsl(bind_conf->bind_proc);
-
- mask = bind_conf->bind_thread[nbproc - 1];
- - if (mask && !(mask & (all_threads_mask ? all_threads_mask : 1UL))) {
- + if (mask && !(mask & all_threads_mask)) {
- unsigned long new_mask = 0;
-
- while (mask) {
- - new_mask |= mask & (all_threads_mask ? all_threads_mask : 1UL);
- + new_mask |= mask & all_threads_mask;
- mask >>= global.nbthread;
- }
-
- diff --git a/src/haproxy.c b/src/haproxy.c
- index 9ba56623..e0186ff9 100644
- --- a/src/haproxy.c
- +++ b/src/haproxy.c
- @@ -2448,8 +2448,7 @@ static void *run_thread_poll_loop(void *data)
- struct per_thread_deinit_fct *ptdf;
- __decl_hathreads(static HA_SPINLOCK_T start_lock);
-
- - tid = *((unsigned int *)data);
- - tid_bit = (1UL << tid);
- + ha_set_tid(*((unsigned int *)data));
- tv_update_date(-1,-1);
-
- list_for_each_entry(ptif, &per_thread_init_list, list) {
- diff --git a/src/hathreads.c b/src/hathreads.c
- index 0d0a0509..238cbb80 100644
- --- a/src/hathreads.c
- +++ b/src/hathreads.c
- @@ -19,8 +19,6 @@
- #include <common/standard.h>
- #include <proto/fd.h>
-
- -THREAD_LOCAL unsigned int tid = 0;
- -THREAD_LOCAL unsigned long tid_bit = (1UL << 0);
-
- /* Dummy I/O handler used by the sync pipe.*/
- void thread_sync_io_handler(int fd)
- @@ -33,6 +31,9 @@ static HA_SPINLOCK_T sync_lock;
- static int threads_sync_pipe[2];
- static unsigned long threads_want_sync = 0;
- volatile unsigned long all_threads_mask = 1; // nbthread 1 assumed by default
- +THREAD_LOCAL unsigned int tid = 0;
- +THREAD_LOCAL unsigned long tid_bit = (1UL << 0);
- +
-
- #if defined(DEBUG_THREAD) || defined(DEBUG_FULL)
- struct lock_stat lock_stats[LOCK_LABELS];
- @@ -130,7 +131,7 @@ void thread_enter_sync()
- {
- static volatile unsigned long barrier = 0;
-
- - if (!all_threads_mask)
- + if (!(all_threads_mask & (all_threads_mask - 1)))
- return;
-
- thread_sync_barrier(&barrier);
- @@ -146,7 +147,7 @@ void thread_exit_sync()
- {
- static volatile unsigned long barrier = 0;
-
- - if (!all_threads_mask)
- + if (!(all_threads_mask & (all_threads_mask - 1)))
- return;
-
- if (threads_want_sync & tid_bit)
|