Skip to content

Commit 8b7a045

Browse files
committed
BUG: f2py: fix issues with thread-local storage define
This is a continuing source of issues, therefore in this commit we: - stop using `threads.h` completely, - better document what is happening, and - ensure the f2py TLS define stays unchanged so users can override it at build time by passing the define as a compile flag. Closes numpygh-27718
1 parent 7c0e2e4 commit 8b7a045

File tree

2 files changed

+21
-14
lines changed

2 files changed

+21
-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: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -548,24 +548,31 @@ 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 them use the same
556+
# compile-time checks as we use for `NPY_TLS` when building NumPy.
557+
#
558+
# __STDC_NO_THREADS__ should not be coupled to the availability of _Thread_local.
559+
# In case we get a bug report, guard it with __STDC_NO_THREADS__ after all.
560+
#
561+
# `thread_local` has become a keyword in C23, but don't try to use that yet
562+
# (too new, doing so while C23 support is preliminary will likely cause more
563+
# problems than it solves).
564+
#
565+
# Note: do not try to use `threads.h`, its availability is very low
566+
# *and* threads.h isn't actually used where `F2PY_THREAD_LOCAL_DECL` is
567+
# in the generated code. See gh-27718 for more details.
551568
cppmacros["F2PY_THREAD_LOCAL_DECL"] = """
552569
#ifndef F2PY_THREAD_LOCAL_DECL
553570
#if defined(_MSC_VER)
554571
#define F2PY_THREAD_LOCAL_DECL __declspec(thread)
555572
#elif defined(NPY_OS_MINGW)
556573
#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
574+
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
575+
#define F2PY_THREAD_LOCAL_DECL _Thread_local
569576
#elif defined(__GNUC__) \\
570577
&& (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 4)))
571578
#define F2PY_THREAD_LOCAL_DECL __thread

0 commit comments

Comments
 (0)