From ae62f05acabbf4cbb2877331befd57ee168a5587 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 1 Nov 2013 09:42:23 -0400 Subject: [PATCH] Fix: tls-compat multi-lib conflict When configured with the TLS pthread key fallback either: - explicitly with ./configure --disable-compiler-tls, - or if compiler TLS is not usable, (this can be confirmed by looking at the configure output: Thread Local Storage (TLS): pthread_getspecific().) There is an issue when using multiple flavors of RCU within the same program. Unit tests concerned: tests/unit/test_urcu_multiflavor tests/unit/test_urcu_multiflavor_dynlink Vladimir Nikulichev noticed crashes when using this setup. The problem can be pinpointed to a missing macro expansion in urcu/tls-compat.h: looking at the output of nm tests/unit/.libs/test_urcu_multiflavor : U __tls_access_rcu_reader this seems to be the issue. We're missing macro expansion in tls-compat.h. With this commit, it becomes: U __tls_access_rcu_reader_bp U __tls_access_rcu_reader_mb U __tls_access_rcu_reader_memb U __tls_access_rcu_reader_sig Please note that this affects an unusual configuration of userspace RCU (with TLS pthread key fallback), needed for some BSD that don't support compiler TLS. Strictly speaking, this requires bumping the URCU library soname version major number, because it breaks the ABI presented to applications on those unusual configurations. A following commit will handle the ABI migration: for stable releases (stable-0.7 and stable-0.8 branches), the ABI is kept compatible, and bogus usage are detected. For the upcoming stable-0.9, the soname will simply be bumped. Reported-by: Vladimir Nikulichev Signed-off-by: Mathieu Desnoyers --- urcu/tls-compat.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/urcu/tls-compat.h b/urcu/tls-compat.h index a44b88d..8ac1ea0 100644 --- a/urcu/tls-compat.h +++ b/urcu/tls-compat.h @@ -74,6 +74,10 @@ extern "C" { #else /* #ifndef CONFIG_RCU_TLS */ +/* + * The *_1() macros ensure macro parameters are expanded. + */ + # include struct urcu_tls { @@ -82,14 +86,16 @@ struct urcu_tls { int init_done; }; -# define DECLARE_URCU_TLS(type, name) \ +# define DECLARE_URCU_TLS_1(type, name) \ type *__tls_access_ ## name(void) +# define DECLARE_URCU_TLS(type, name) \ + DECLARE_URCU_TLS_1(type, name) /* * Note: we don't free memory at process exit, since it will be dealt * with by the OS. */ -# define DEFINE_URCU_TLS(type, name) \ +# define DEFINE_URCU_TLS_1(type, name) \ type *__tls_access_ ## name(void) \ { \ static struct urcu_tls __tls_ ## name = { \ @@ -118,7 +124,12 @@ struct urcu_tls { return __tls_p; \ } -# define URCU_TLS(name) (*__tls_access_ ## name()) +# define DEFINE_URCU_TLS(type, name) \ + DEFINE_URCU_TLS_1(type, name) + +# define URCU_TLS_1(name) (*__tls_access_ ## name()) + +# define URCU_TLS(name) URCU_TLS_1(name) #endif /* #else #ifndef CONFIG_RCU_TLS */ -- 2.34.1