]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-81057: Move Threading-Related Globals to _PyRuntimeState (#100084)
authorEric Snow <ericsnowcurrently@gmail.com>
Fri, 9 Dec 2022 00:50:58 +0000 (17:50 -0700)
committerGitHub <noreply@github.com>
Fri, 9 Dec 2022 00:50:58 +0000 (17:50 -0700)
https://github.com/python/cpython/issues/81057

Include/internal/pycore_pythread.h [new file with mode: 0644]
Include/internal/pycore_runtime.h
Makefile.pre.in
PCbuild/pythoncore.vcxproj
PCbuild/pythoncore.vcxproj.filters
Python/thread.c
Python/thread_nt.h
Python/thread_pthread.h
Python/thread_pthread_stubs.h
Tools/c-analyzer/cpython/globals-to-fix.tsv
Tools/c-analyzer/cpython/ignored.tsv

diff --git a/Include/internal/pycore_pythread.h b/Include/internal/pycore_pythread.h
new file mode 100644 (file)
index 0000000..4aeb285
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef Py_INTERNAL_PYTHREAD_H
+#define Py_INTERNAL_PYTHREAD_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+#ifndef _POSIX_THREADS
+/* This means pthreads are not implemented in libc headers, hence the macro
+   not present in unistd.h. But they still can be implemented as an external
+   library (e.g. gnu pth in pthread emulation) */
+# ifdef HAVE_PTHREAD_H
+#  include <pthread.h> /* _POSIX_THREADS */
+# endif
+# ifndef _POSIX_THREADS
+/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
+   enough of the Posix threads package is implemented to support python
+   threads.
+
+   This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
+   a check of __ia64 to verify that we're running on an ia64 system instead
+   of a pa-risc system.
+*/
+#  ifdef __hpux
+#   ifdef _SC_THREADS
+#    define _POSIX_THREADS
+#   endif
+#  endif
+# endif /* _POSIX_THREADS */
+#endif /* _POSIX_THREADS */
+
+#if defined(_POSIX_THREADS) && !defined(HAVE_PTHREAD_STUBS)
+# define _USE_PTHREADS
+#endif
+
+#if defined(_USE_PTHREADS) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+// monotonic is supported statically.  It doesn't mean it works on runtime.
+# define CONDATTR_MONOTONIC
+#endif
+
+
+#if defined(HAVE_PTHREAD_STUBS)
+// pthread_key
+struct py_stub_tls_entry {
+    bool in_use;
+    void *value;
+};
+#endif
+
+struct _pythread_runtime_state {
+    int initialized;
+
+#ifdef _USE_PTHREADS
+    // This matches when thread_pthread.h is used.
+    struct {
+        /* NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported. */
+        pthread_condattr_t *ptr;
+# ifdef CONDATTR_MONOTONIC
+    /* The value to which condattr_monotonic is set. */
+        pthread_condattr_t val;
+# endif
+    } _condattr_monotonic;
+
+#endif  // USE_PTHREADS
+
+#if defined(HAVE_PTHREAD_STUBS)
+    struct {
+        struct py_stub_tls_entry tls_entries[PTHREAD_KEYS_MAX];
+    } stubs;
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_PYTHREAD_H */
index ac89c7d378e26f4b3b3badcd8211ce02f50ea27a..fe2de5feb47ae3c6ed0ad1d848349eed3aafefe5 100644 (file)
@@ -20,6 +20,7 @@ extern "C" {
 #include "pycore_parser.h"          // struct _parser_runtime_state
 #include "pycore_pymem.h"           // struct _pymem_allocators
 #include "pycore_pyhash.h"          // struct pyhash_runtime_state
+#include "pycore_pythread.h"        // struct _pythread_runtime_state
 #include "pycore_obmalloc.h"        // struct obmalloc_state
 #include "pycore_time.h"            // struct _time_runtime_state
 #include "pycore_unicodeobject.h"   // struct _Py_unicode_runtime_ids
@@ -96,6 +97,7 @@ typedef struct pyruntimestate {
         int unhandled_keyboard_interrupt;
     } signals;
     struct _time_runtime_state time;
+    struct _pythread_runtime_state threads;
 
     struct pyinterpreters {
         PyThread_type_lock mutex;
index 312031999df00290546dc5b1af28c0abde499366..de42d684f16602820a201007332030a712edfa68 100644 (file)
@@ -1663,6 +1663,7 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/internal/pycore_pymem.h \
                $(srcdir)/Include/internal/pycore_pymem_init.h \
                $(srcdir)/Include/internal/pycore_pystate.h \
+               $(srcdir)/Include/internal/pycore_pythread.h \
                $(srcdir)/Include/internal/pycore_range.h \
                $(srcdir)/Include/internal/pycore_runtime.h \
                $(srcdir)/Include/internal/pycore_runtime_init_generated.h \
index 58ea6ae7b4aa17e75f3ff69419b22c133007b9cc..35fbff320f46612bb219d5513f715c075488405c 100644 (file)
     <ClInclude Include="..\Include\internal\pycore_pymem.h" />
     <ClInclude Include="..\Include\internal\pycore_pymem_init.h" />
     <ClInclude Include="..\Include\internal\pycore_pystate.h" />
+    <ClInclude Include="..\Include\internal\pycore_pythread.h" />
     <ClInclude Include="..\Include\internal\pycore_range.h" />
     <ClInclude Include="..\Include\internal\pycore_runtime.h" />
     <ClInclude Include="..\Include\internal\pycore_runtime_init.h" />
index 96c3bd6c30e973e553140b603075090574039fc2..19cb5cf1c8073526a3ef01ab98f083bad18a1446 100644 (file)
     <ClInclude Include="..\Include\internal\pycore_pystate.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_pythread.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_range.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
index 3c1e78ed1bca839d87657678866b73c58bb23c7f..4581f1af043a37f16833aa08820b78fa449818f5 100644 (file)
@@ -8,15 +8,7 @@
 #include "Python.h"
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
 #include "pycore_structseq.h"     // _PyStructSequence_FiniType()
-
-#ifndef _POSIX_THREADS
-/* This means pthreads are not implemented in libc headers, hence the macro
-   not present in unistd.h. But they still can be implemented as an external
-   library (e.g. gnu pth in pthread emulation) */
-# ifdef HAVE_PTHREAD_H
-#  include <pthread.h> /* _POSIX_THREADS */
-# endif
-#endif
+#include "pycore_pythread.h"
 
 #ifndef DONT_HAVE_STDIO_H
 #include <stdio.h>
 
 #include <stdlib.h>
 
-#ifndef _POSIX_THREADS
-
-/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
-   enough of the Posix threads package is implemented to support python
-   threads.
-
-   This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
-   a check of __ia64 to verify that we're running on an ia64 system instead
-   of a pa-risc system.
-*/
-#ifdef __hpux
-#ifdef _SC_THREADS
-#define _POSIX_THREADS
-#endif
-#endif
-
-#endif /* _POSIX_THREADS */
-
-static int initialized;
 
 static void PyThread__init_thread(void); /* Forward */
 
+#define initialized _PyRuntime.threads.initialized
+
 void
 PyThread_init_thread(void)
 {
-    if (initialized)
+    if (initialized) {
         return;
+    }
     initialized = 1;
     PyThread__init_thread();
 }
@@ -58,7 +34,7 @@ PyThread_init_thread(void)
 #if defined(HAVE_PTHREAD_STUBS)
 #   define PYTHREAD_NAME "pthread-stubs"
 #   include "thread_pthread_stubs.h"
-#elif defined(_POSIX_THREADS)
+#elif defined(_USE_PTHREADS)  /* AKA _PTHREADS */
 #   if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)
 #     define PYTHREAD_NAME "pthread-stubs"
 #   else
index d1f1323948a6c67756215e8c5e013d30e05bc533..26f441bd6d3c569da03069d0267a4c966fc6cc97 100644 (file)
@@ -152,11 +152,12 @@ unsigned long PyThread_get_thread_native_id(void);
 #endif
 
 /*
- * Initialization of the C package, should not be needed.
+ * Initialization for the current runtime.
  */
 static void
 PyThread__init_thread(void)
 {
+    // Initialization of the C package should not be needed.
 }
 
 /*
index 1c5b320813af83dbf803475e2003fa3a6b6f5425..ae312e987bd6ad85dd8de44fda64ad6bb9d3d00a 100644 (file)
  * pthread_cond support
  */
 
-#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
-// monotonic is supported statically.  It doesn't mean it works on runtime.
-#define CONDATTR_MONOTONIC
-#endif
-
-// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
-static pthread_condattr_t *condattr_monotonic = NULL;
+#define condattr_monotonic _PyRuntime.threads._condattr_monotonic.ptr
 
 static void
 init_condattr(void)
 {
 #ifdef CONDATTR_MONOTONIC
-    static pthread_condattr_t ca;
+# define ca _PyRuntime.threads._condattr_monotonic.val
+    // XXX We need to check the return code?
     pthread_condattr_init(&ca);
+    // XXX We need to run pthread_condattr_destroy() during runtime fini.
     if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
         condattr_monotonic = &ca;  // Use monotonic clock
     }
@@ -192,15 +188,21 @@ typedef struct {
     "%s: %s\n", name, strerror(status)); error = 1; }
 
 /*
- * Initialization.
+ * Initialization for the current runtime.
  */
 static void
 PyThread__init_thread(void)
 {
+    // The library is only initialized once in the process,
+    // regardless of how many times the Python runtime is initialized.
+    static int lib_initialized = 0;
+    if (!lib_initialized) {
+        lib_initialized = 1;
 #if defined(_AIX) && defined(__GNUC__)
-    extern void pthread_init(void);
-    pthread_init();
+        extern void pthread_init(void);
+        pthread_init();
 #endif
+    }
     init_condattr();
 }
 
index 8b80c0f87e25097b0efde717c8d289f043f635c9..56e5b6141924b4005021807f92d6df7a4b5ac48d 100644 (file)
@@ -124,13 +124,10 @@ pthread_attr_destroy(pthread_attr_t *attr)
     return 0;
 }
 
-// pthread_key
-typedef struct {
-    bool in_use;
-    void *value;
-} py_tls_entry;
 
-static py_tls_entry py_tls_entries[PTHREAD_KEYS_MAX] = {0};
+typedef struct py_stub_tls_entry py_tls_entry;
+
+#define py_tls_entries (_PyRuntime.threads.stubs.tls_entries)
 
 int
 pthread_key_create(pthread_key_t *key, void (*destr_function)(void *))
index f774cdeab3863728edf57aad43a7283781903569..94e9831db1fdb6ed998f02ea6d9a4d9af322aebd 100644 (file)
@@ -306,7 +306,6 @@ Objects/sliceobject.c       -       _Py_EllipsisObject      -
 ## state
 
 Objects/object.c       -       _Py_RefTotal    -
-Python/thread_pthread_stubs.h  -       py_tls_entries  -
 
 
 ##################################
index 814c55b75c090df50bfc9e134f9f250c798aa7c1..7d6ff0ba6d64429a8523b4a9f468117a395bac44 100644 (file)
@@ -22,11 +22,8 @@ Python/fileutils.c   set_inheritable ioctl_works     -
 # XXX Is this thread-safe?
 Modules/posixmodule.c  os_dup2_impl    dup3_works      -
 
-## resource init - set during first init
-Python/thread.c        -       initialized     -
-Python/thread_pthread.h        -       condattr_monotonic      -
-# safe static buffer used during one-time initialization
-Python/thread_pthread.h        init_condattr   ca      -
+## guards around resource init
+Python/thread_pthread.h        PyThread__init_thread   lib_initialized -
 
 ##-----------------------
 ## other values (not Python-specific)