diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake index f9b6c48a1..63a79eb7b 100644 --- a/cmake/ConfigureChecks.cmake +++ b/cmake/ConfigureChecks.cmake @@ -186,6 +186,16 @@ int main () { HAVE_STD__MAKE_UNIQUE ) +# Detect support for thread_local. +check_cxx_source_compiles(" +int main () { + static thread_local int x = 3; + (void)x; +} +" + HAVE_CX11_THREAD_LOCAL +) + find_program(SED sed) check_cxx_source_compiles(" diff --git a/config_cmake.h.in b/config_cmake.h.in index 0330940fa..de86ab185 100644 --- a/config_cmake.h.in +++ b/config_cmake.h.in @@ -10,6 +10,9 @@ /* Define to 1 if you have the `ctermid_r' function. */ #cmakedefine HAVE_CTERMID_R 1 +/* Define to 1 if C++11 thread_local is supported. */ +#cmakedefine HAVE_CX11_THREAD_LOCAL 1 + /* Define to 1 if you have the `dirfd' function. */ #cmakedefine HAVE_DIRFD 1 diff --git a/src/fallback.h b/src/fallback.h index f9788755b..6bda9f6c7 100644 --- a/src/fallback.h +++ b/src/fallback.h @@ -34,6 +34,18 @@ int fish_wcswidth(const wchar_t *str, size_t n); // otherwise it uses mkstemp followed by fcntl int fish_mkstemp_cloexec(char *); +/// thread_local support. +#if HAVE_CX11_THREAD_LOCAL +# define FISH_THREAD_LOCAL thread_local +#elif defined (__GNUC__) +# define FISH_THREAD_LOCAL __thread +#elif defined (_MSC_VER) +# define FISH_THREAD_LOCAL __declspec(thread) +#else // !C++11 && !__GNUC__ && !_MSC_VER +# error "No known thread local storage qualifier for this platform" +#endif + + #ifndef WCHAR_MAX /// This _should_ be defined by wchar.h, but e.g. OpenBSD doesn't. #define WCHAR_MAX INT_MAX diff --git a/src/iothread.cpp b/src/iothread.cpp index c7a32f376..ab6504971 100644 --- a/src/iothread.cpp +++ b/src/iothread.cpp @@ -491,7 +491,7 @@ static uint64_t next_thread_id() { } uint64_t thread_id() { - static thread_local uint64_t tl_tid = next_thread_id(); + static FISH_THREAD_LOCAL uint64_t tl_tid = next_thread_id(); return tl_tid; }