From 109267f653502cf5ef5ada5d098167b9726daa2d Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 20 Apr 2020 11:30:49 -0400 Subject: [PATCH 1/1] Fix: tls-compat.h exposes compiler-dependent public configuration Exposing the storage class chosen by ax_tls.m4 in a public header is a bad idea, because if a recent gcc is used when configuring liburcu, thus detecting C11, it will choose _Thread_local. Then, if an external project uses urcu/tls-compat.h with an older gcc (e.g. 4.8), it will fail to build, because that storage class is unknown, and __thread should be used instead. Therefore, use a preprocessor conditional on __cplusplus to detect C++11 (and use thread_local). Else, the STDC version is used to select _Thread_local. Else check if _MSC_VER is defined to select __declspec(thread), or else rely on __thread as fallback. Remove ax_tls.m4 because it is now unused. Signed-off-by: Mathieu Desnoyers --- configure.ac | 11 ++---- include/urcu/tls-compat.h | 18 +++++++--- m4/ax_tls.m4 | 74 --------------------------------------- 3 files changed, 16 insertions(+), 87 deletions(-) delete mode 100644 m4/ax_tls.m4 diff --git a/configure.ac b/configure.ac index c80b918..b62f587 100644 --- a/configure.ac +++ b/configure.ac @@ -50,14 +50,7 @@ AC_USE_SYSTEM_EXTENSIONS AC_PROG_CC AC_PROG_CC_STDC -# If not overridden, use ax_tls.m4 to check if TLS is available. -AS_IF([test "x$def_compiler_tls" = "xyes"], - [AX_TLS([def_tls_detect=$ac_cv_tls], [:])], - [:]) - -AS_IF([test "x$def_tls_detect" = "x"], - [:], - [AC_DEFINE_UNQUOTED([CONFIG_RCU_TLS], $def_tls_detect)]) +AS_IF([test "x$def_compiler_tls" = "xyes"], AC_DEFINE([CONFIG_RCU_TLS], [1]), [:]) # Checks for programs. AC_PROG_AWK @@ -501,7 +494,7 @@ test "x$compat_futex_test" = "x0" && value=1 || value=0 PPRINT_PROP_BOOL([Futex support], $value) # TLS -test "x$def_tls_detect" = "x" && value="pthread_getspecific()" || value="$def_tls_detect" +test "x$def_compiler_tls" = "xyes" && value="compiler TLS" || value="pthread_getspecific()" PPRINT_PROP_STRING([Thread Local Storage (TLS)], [$value]) # clock_gettime() available diff --git a/include/urcu/tls-compat.h b/include/urcu/tls-compat.h index c17aca3..db22dde 100644 --- a/include/urcu/tls-compat.h +++ b/include/urcu/tls-compat.h @@ -32,7 +32,17 @@ extern "C" { #endif -#ifdef CONFIG_RCU_TLS /* Based on ax_tls.m4 */ +#ifdef CONFIG_RCU_TLS + +#if defined (__cplusplus) && __cplusplus >= 201103L +# define URCU_TLS_STORAGE_CLASS thread_local +#elif defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +# define URCU_TLS_STORAGE_CLASS _Thread_local +#elif defined (_MSC_VER) +# define URCU_TLS_STORAGE_CLASS __declspec(thread) +#else +# define URCU_TLS_STORAGE_CLASS __thread +#endif /* * Hint: How to define/declare TLS variables of compound types @@ -65,13 +75,13 @@ extern "C" { */ # define DECLARE_URCU_TLS(type, name) \ - CONFIG_RCU_TLS type name + URCU_TLS_STORAGE_CLASS type name # define DEFINE_URCU_TLS(type, name) \ - CONFIG_RCU_TLS type name + URCU_TLS_STORAGE_CLASS type name # define DEFINE_URCU_TLS_INIT(type, name, init) \ - CONFIG_RCU_TLS type name = (init) + URCU_TLS_STORAGE_CLASS type name = (init) # define URCU_TLS(name) (name) diff --git a/m4/ax_tls.m4 b/m4/ax_tls.m4 deleted file mode 100644 index 51edee8..0000000 --- a/m4/ax_tls.m4 +++ /dev/null @@ -1,74 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_tls.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_TLS([action-if-found], [action-if-not-found]) -# -# DESCRIPTION -# -# Provides a test for the compiler support of thread local storage (TLS) -# extensions. Defines TLS if it is found. Currently knows about C++11, -# GCC/ICC, and MSVC. I think SunPro uses the same as GCC, and Borland -# apparently supports either. -# -# LICENSE -# -# Copyright (c) 2008 Alan Woodland -# Copyright (c) 2010 Diego Elio Petteno` -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 14 - -AC_DEFUN([AX_TLS], [ - AC_MSG_CHECKING([for thread local storage (TLS) class]) - AC_CACHE_VAL([ac_cv_tls], - [for ax_tls_keyword in thread_local _Thread_local __thread '__declspec(thread)' none; do - AS_CASE([$ax_tls_keyword], - [none], [ac_cv_tls=none ; break], - [AC_TRY_COMPILE( - [#include - static void - foo(void) { - static ] $ax_tls_keyword [ int bar; - exit(1); - }], - [], - [ac_cv_tls=$ax_tls_keyword ; break], - ac_cv_tls=none - )]) - done - ]) - AC_MSG_RESULT([$ac_cv_tls]) - - AS_IF([test "$ac_cv_tls" != "none"], - [AC_DEFINE_UNQUOTED([TLS],[$ac_cv_tls],[If the compiler supports a TLS storage class define it to that here]) - m4_ifnblank([$1],[$1])], - [m4_ifnblank([$2],[$2])]) -]) -- 2.34.1