gh-81057: Move Threading-Related Globals to _PyRuntimeState (#100084)

https://github.com/python/cpython/issues/81057
This commit is contained in:
Eric Snow 2022-12-08 17:50:58 -07:00 committed by GitHub
parent bc8cdf8c3d
commit 1160001b34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 114 additions and 54 deletions

View file

@ -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 */

View 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;

View 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 \

View file

@ -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" />

View file

@ -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>

View 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>
@ -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

View 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.
}
/*

View file

@ -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();
}

View 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 *))

View file

@ -306,7 +306,6 @@ Objects/sliceobject.c - _Py_EllipsisObject -
## state
Objects/object.c - _Py_RefTotal -
Python/thread_pthread_stubs.h - py_tls_entries -
##################################

Can't render this file because it has a wrong number of fields in line 4.

View 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)

Can't render this file because it has a wrong number of fields in line 4.