Skip to content

Commit 060c28a

Browse files
authored
Merge pull request numpy#27729 from rgommers/f2py-tls
BUG: f2py: fix issues with thread-local storage define
2 parents 50d64e5 + f4b8a80 commit 060c28a

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

numpy/_core/meson.build

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ endforeach
245245

246246
# variable attributes tested via "int %s a" % attribute
247247
optional_variable_attributes = [
248-
['thread_local', 'HAVE_THREAD_LOCAL'],
249-
['_Thread_local', 'HAVE__THREAD_LOCAL'],
248+
['thread_local', 'HAVE_THREAD_LOCAL'], # C23
249+
['_Thread_local', 'HAVE__THREAD_LOCAL'], # C11/C17
250250
['__thread', 'HAVE__THREAD'],
251251
['__declspec(thread)', 'HAVE___DECLSPEC_THREAD_']
252252
]

numpy/f2py/cfuncs.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -548,24 +548,32 @@ def errmess(s: str) -> None:
548548
#error You need to install NumPy version 0.13 or higher. See https://scipy.org/install.html
549549
#endif
550550
"""
551+
552+
# Defining the correct value to indicate thread-local storage in C without
553+
# running a compile-time check (which we have no control over in generated
554+
# code used outside of NumPy) is hard. Therefore we support overriding this
555+
# via an external define - the f2py-using package can then use the same
556+
# compile-time checks as we use for `NPY_TLS` when building NumPy (see
557+
# scipy#21860 for an example of that).
558+
#
559+
# __STDC_NO_THREADS__ should not be coupled to the availability of _Thread_local.
560+
# In case we get a bug report, guard it with __STDC_NO_THREADS__ after all.
561+
#
562+
# `thread_local` has become a keyword in C23, but don't try to use that yet
563+
# (too new, doing so while C23 support is preliminary will likely cause more
564+
# problems than it solves).
565+
#
566+
# Note: do not try to use `threads.h`, its availability is very low
567+
# *and* threads.h isn't actually used where `F2PY_THREAD_LOCAL_DECL` is
568+
# in the generated code. See gh-27718 for more details.
551569
cppmacros["F2PY_THREAD_LOCAL_DECL"] = """
552570
#ifndef F2PY_THREAD_LOCAL_DECL
553571
#if defined(_MSC_VER)
554572
#define F2PY_THREAD_LOCAL_DECL __declspec(thread)
555573
#elif defined(NPY_OS_MINGW)
556574
#define F2PY_THREAD_LOCAL_DECL __thread
557-
#elif defined(__STDC_VERSION__) \\
558-
&& (__STDC_VERSION__ >= 201112L) \\
559-
&& !defined(__STDC_NO_THREADS__) \\
560-
&& (!defined(__GLIBC__) || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 12)) \\
561-
&& !defined(NPY_OS_OPENBSD) && !defined(NPY_OS_HAIKU)
562-
/* __STDC_NO_THREADS__ was first defined in a maintenance release of glibc 2.12,
563-
see https://lists.gnu.org/archive/html/commit-hurd/2012-07/msg00180.html,
564-
so `!defined(__STDC_NO_THREADS__)` may give false positive for the existence
565-
of `threads.h` when using an older release of glibc 2.12
566-
See gh-19437 for details on OpenBSD */
567-
#include <threads.h>
568-
#define F2PY_THREAD_LOCAL_DECL thread_local
575+
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
576+
#define F2PY_THREAD_LOCAL_DECL _Thread_local
569577
#elif defined(__GNUC__) \\
570578
&& (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 4)))
571579
#define F2PY_THREAD_LOCAL_DECL __thread

0 commit comments

Comments
 (0)