Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions Include/internal/pycore_pythread.h
Original file line number Diff line number Diff line change
@@ -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 */
2 changes: 2 additions & 0 deletions Include/internal/pycore_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
1 change: 1 addition & 0 deletions PCbuild/pythoncore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
3 changes: 3 additions & 0 deletions PCbuild/pythoncore.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
36 changes: 6 additions & 30 deletions Python/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,33 @@
#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>
#endif

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

#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
Expand Down
3 changes: 2 additions & 1 deletion Python/thread_nt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}

/*
Expand Down
24 changes: 13 additions & 11 deletions Python/thread_pthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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();
}

Expand Down
9 changes: 3 additions & 6 deletions Python/thread_pthread_stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *))
Expand Down
1 change: 0 additions & 1 deletion Tools/c-analyzer/cpython/globals-to-fix.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ Objects/sliceobject.c - _Py_EllipsisObject -
## state

Objects/object.c - _Py_RefTotal -
Python/thread_pthread_stubs.h - py_tls_entries -


##################################
Expand Down
7 changes: 2 additions & 5 deletions Tools/c-analyzer/cpython/ignored.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down