summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_pythread.h81
-rw-r--r--Include/internal/pycore_runtime.h2
-rw-r--r--Makefile.pre.in1
-rw-r--r--PCbuild/pythoncore.vcxproj1
-rw-r--r--PCbuild/pythoncore.vcxproj.filters3
-rw-r--r--Python/thread.c36
-rw-r--r--Python/thread_nt.h3
-rw-r--r--Python/thread_pthread.h24
-rw-r--r--Python/thread_pthread_stubs.h9
-rw-r--r--Tools/c-analyzer/cpython/globals-to-fix.tsv1
-rw-r--r--Tools/c-analyzer/cpython/ignored.tsv7
11 files changed, 114 insertions, 54 deletions
diff --git a/Include/internal/pycore_pythread.h b/Include/internal/pycore_pythread.h
new file mode 100644
index 0000000..4aeb285
--- /dev/null
+++ b/Include/internal/pycore_pythread.h
@@ -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 */
diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h
index ac89c7d..fe2de5f 100644
--- a/Include/internal/pycore_runtime.h
+++ b/Include/internal/pycore_runtime.h
@@ -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;
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 3120319..de42d68 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -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 \
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index 58ea6ae..35fbff3 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -245,6 +245,7 @@
<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" />
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index 96c3bd6..19cb5cf 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -639,6 +639,9 @@
<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>
diff --git a/Python/thread.c b/Python/thread.c
index 3c1e78e..4581f1a 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -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>
@@ -24,33 +16,17 @@
#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
diff --git a/Python/thread_nt.h b/Python/thread_nt.h
index d1f1323..26f441b 100644
--- a/Python/thread_nt.h
+++ b/Python/thread_nt.h
@@ -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.
}
/*
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index 1c5b320..ae312e9 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -119,20 +119,16 @@
* 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();
}
diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h
index 8b80c0f..56e5b61 100644
--- a/Python/thread_pthread_stubs.h
+++ b/Python/thread_pthread_stubs.h
@@ -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 *))
diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv
index f774cde..94e9831 100644
--- a/Tools/c-analyzer/cpython/globals-to-fix.tsv
+++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv
@@ -306,7 +306,6 @@ Objects/sliceobject.c - _Py_EllipsisObject -
## state
Objects/object.c - _Py_RefTotal -
-Python/thread_pthread_stubs.h - py_tls_entries -
##################################
diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv
index 814c55b..7d6ff0b 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -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)