From f5809cde7a7412caeb01fc7852e392dec1a3296a Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sat, 26 Jan 2019 13:35:03 +0100 Subject: [PATCH] MINOR: threads: make MAX_THREADS configurable at build time There's some value in being able to limit MAX_THREADS, either to save precious resources in embedded environments, or to protect certain deployments against accidently incorrect settings. With this patch, if MAX_THREADS is defined at build time, it will be used. However, given that LONGBITS is not a macro but is defined according to sizeof(long), we can't check the value range at build time and instead we need to perform the check at early boot time. However, the compiler is able to optimize away the constant comparisons and doesn't even emit the check code when values are correct. The output message regarding threading support was improved to report the number of threads. --- include/common/hathreads.h | 5 ++++- src/hathreads.c | 13 +++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/common/hathreads.h b/include/common/hathreads.h index 8e96e37e8..019d74970 100644 --- a/include/common/hathreads.h +++ b/include/common/hathreads.h @@ -168,8 +168,11 @@ static inline unsigned long thread_isolated() #include #include +#ifndef MAX_THREADS #define MAX_THREADS LONGBITS -#define MAX_THREADS_MASK ((unsigned long)-1) +#endif + +#define MAX_THREADS_MASK (~0UL >> (LONGBITS - MAX_THREADS)) #define __decl_hathreads(decl) decl diff --git a/src/hathreads.c b/src/hathreads.c index 39ff7e828..a21bddd9e 100644 --- a/src/hathreads.c +++ b/src/hathreads.c @@ -108,13 +108,22 @@ void ha_rwlock_init(HA_RWLOCK_T *l) __attribute__((constructor)) static void __hathreads_init(void) { + char *ptr = NULL; + + if (MAX_THREADS < 1 || MAX_THREADS > LONGBITS) { + ha_alert("MAX_THREADS value must be between 1 and %d inclusive; " + "HAProxy was built with value %d, please fix it and rebuild.\n", + LONGBITS, MAX_THREADS); + exit(1); + } + memprintf(&ptr, "Built with multi-threading support (MAX_THREADS=%d).", MAX_THREADS); + hap_register_build_opts(ptr, 1); + #if defined(DEBUG_THREAD) || defined(DEBUG_FULL) memset(lock_stats, 0, sizeof(lock_stats)); #endif } -REGISTER_BUILD_OPTS("Built with multi-threading support."); - #else REGISTER_BUILD_OPTS("Built without multi-threading support (USE_THREAD not set).");