Skip to content

Commit a67fef0

Browse files
committed
gh-112535: Implement fallback implementation of _Py_ThreadId()
1 parent fddc829 commit a67fef0

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

Include/object.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,16 @@ PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y);
239239
#define Py_Is(x, y) ((x) == (y))
240240

241241
#if defined(Py_GIL_DISABLED) && !defined(Py_LIMITED_API)
242+
243+
#ifdef thread_local
244+
static thread_local int __tp = 0;
245+
# define HAVE_THREAD_ID_FALLBACK 1
246+
#elif defined(__GNUC__)
247+
// Assume that we only support C11 compilers.
248+
static __thread int __tp = 0;
249+
# define HAVE_THREAD_ID_FALLBACK 1
250+
#endif
251+
242252
static inline uintptr_t
243253
_Py_ThreadId(void)
244254
{
@@ -283,6 +293,13 @@ _Py_ThreadId(void)
283293
// Both GCC and Clang have supported __builtin_thread_pointer
284294
// for s390 from long time ago.
285295
tid = (uintptr_t)__builtin_thread_pointer();
296+
#elif defined(HAVE_THREAD_ID_FALLBACK)
297+
// Hack: Using characteristics of TLS address mapping.
298+
// The address of the thread-local variable is not equal as the actual thread pointer,
299+
// However, it has the property of being fixed at runtime, with no duplication of values
300+
// between different threads. Since it requires offset calculation, it is more expensive
301+
// than __builtin_thread_pointer().
302+
tid = (uintptr_t)&__tp;
286303
#else
287304
# error "define _Py_ThreadId for this platform"
288305
#endif

0 commit comments

Comments
 (0)