summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_pystate.h122
-rw-r--r--Include/internal/pycore_runtime.h143
-rw-r--r--Makefile.pre.in1
-rw-r--r--PCbuild/pythoncore.vcxproj1
-rw-r--r--PCbuild/pythoncore.vcxproj.filters3
-rw-r--r--Python/pylifecycle.c2
-rw-r--r--Python/pystate.c5
7 files changed, 152 insertions, 125 deletions
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index c28df89..c9275a7 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -11,6 +11,7 @@ extern "C" {
#include "pycore_gil.h" /* struct _gil_runtime_state */
#include "pycore_pymem.h" /* struct _gc_runtime_state */
#include "pycore_warnings.h" /* struct _warnings_runtime_state */
+#include "pycore_runtime.h" /* PyRuntimestate */
/* ceval state */
@@ -32,15 +33,6 @@ struct _pending_calls {
int last;
};
-struct _ceval_runtime_state {
- int recursion_limit;
- /* Request for dropping the GIL */
- _Py_atomic_int gil_drop_request;
- /* Request for checking signals. */
- _Py_atomic_int signals_pending;
- struct _gil_runtime_state gil;
-};
-
struct _ceval_state {
/* Records whether tracing is on for any thread. Counts the number
of threads for which tstate->c_tracefunc is non-NULL, so if the
@@ -176,118 +168,6 @@ struct _xidregitem {
struct _xidregitem *next;
};
-/* runtime audit hook state */
-
-typedef struct _Py_AuditHookEntry {
- struct _Py_AuditHookEntry *next;
- Py_AuditHookFunction hookCFunction;
- void *userData;
-} _Py_AuditHookEntry;
-
-/* GIL state */
-
-struct _gilstate_runtime_state {
- int check_enabled;
- /* Assuming the current thread holds the GIL, this is the
- PyThreadState for the current thread. */
- _Py_atomic_address tstate_current;
- /* The single PyInterpreterState used by this process'
- GILState implementation
- */
- /* TODO: Given interp_main, it may be possible to kill this ref */
- PyInterpreterState *autoInterpreterState;
- Py_tss_t autoTSSkey;
-};
-
-/* Issue #26558: Flag to disable PyGILState_Check().
- If set to non-zero, PyGILState_Check() always return 1. */
-#define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled
-
-
-/* Full Python runtime state */
-
-typedef struct pyruntimestate {
- /* Is running Py_PreInitialize()? */
- int preinitializing;
-
- /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */
- int preinitialized;
-
- /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
- int core_initialized;
-
- /* Is Python fully initialized? Set to 1 by Py_Initialize() */
- int initialized;
-
- /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
- is called again.
-
- Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing()
- to access it, don't access it directly. */
- _Py_atomic_address _finalizing;
-
- struct pyinterpreters {
- PyThread_type_lock mutex;
- PyInterpreterState *head;
- PyInterpreterState *main;
- /* _next_interp_id is an auto-numbered sequence of small
- integers. It gets initialized in _PyInterpreterState_Init(),
- which is called in Py_Initialize(), and used in
- PyInterpreterState_New(). A negative interpreter ID
- indicates an error occurred. The main interpreter will
- always have an ID of 0. Overflow results in a RuntimeError.
- If that becomes a problem later then we can adjust, e.g. by
- using a Python int. */
- int64_t next_id;
- } interpreters;
- // XXX Remove this field once we have a tp_* slot.
- struct _xidregistry {
- PyThread_type_lock mutex;
- struct _xidregitem *head;
- } xidregistry;
-
- unsigned long main_thread;
-
-#define NEXITFUNCS 32
- void (*exitfuncs[NEXITFUNCS])(void);
- int nexitfuncs;
-
- struct _ceval_runtime_state ceval;
- struct _gilstate_runtime_state gilstate;
-
- PyPreConfig preconfig;
-
- Py_OpenCodeHookFunction open_code_hook;
- void *open_code_userdata;
- _Py_AuditHookEntry *audit_hook_head;
-
- // XXX Consolidate globals found via the check-c-globals script.
-} _PyRuntimeState;
-
-#define _PyRuntimeState_INIT \
- {.preinitialized = 0, .core_initialized = 0, .initialized = 0}
-/* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
-
-PyAPI_DATA(_PyRuntimeState) _PyRuntime;
-PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
-PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
-PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
-
-/* Initialize _PyRuntimeState.
- Return NULL on success, or return an error message on failure. */
-PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
-
-PyAPI_FUNC(void) _PyRuntime_Finalize(void);
-
-static inline PyThreadState*
-_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
- return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
-}
-
-static inline void
-_PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
- _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
-}
/* Check if the current thread is the main thread.
Use _Py_IsMainInterpreter() to check if it's the main interpreter. */
diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h
new file mode 100644
index 0000000..54dbaeb
--- /dev/null
+++ b/Include/internal/pycore_runtime.h
@@ -0,0 +1,143 @@
+#ifndef Py_INTERNAL_RUNTIME_H
+#define Py_INTERNAL_RUNTIME_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_atomic.h" /* _Py_atomic_address */
+#include "pycore_gil.h" // struct _gil_runtime_state
+
+/* ceval state */
+
+struct _ceval_runtime_state {
+ int recursion_limit;
+ /* Request for dropping the GIL */
+ _Py_atomic_int gil_drop_request;
+ /* Request for checking signals. */
+ _Py_atomic_int signals_pending;
+ struct _gil_runtime_state gil;
+};
+
+/* GIL state */
+
+struct _gilstate_runtime_state {
+ /* bpo-26558: Flag to disable PyGILState_Check().
+ If set to non-zero, PyGILState_Check() always return 1. */
+ int check_enabled;
+ /* Assuming the current thread holds the GIL, this is the
+ PyThreadState for the current thread. */
+ _Py_atomic_address tstate_current;
+ /* The single PyInterpreterState used by this process'
+ GILState implementation
+ */
+ /* TODO: Given interp_main, it may be possible to kill this ref */
+ PyInterpreterState *autoInterpreterState;
+ Py_tss_t autoTSSkey;
+};
+
+/* Runtime audit hook state */
+
+typedef struct _Py_AuditHookEntry {
+ struct _Py_AuditHookEntry *next;
+ Py_AuditHookFunction hookCFunction;
+ void *userData;
+} _Py_AuditHookEntry;
+
+/* Full Python runtime state */
+
+typedef struct pyruntimestate {
+ /* Is running Py_PreInitialize()? */
+ int preinitializing;
+
+ /* Is Python preinitialized? Set to 1 by Py_PreInitialize() */
+ int preinitialized;
+
+ /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
+ int core_initialized;
+
+ /* Is Python fully initialized? Set to 1 by Py_Initialize() */
+ int initialized;
+
+ /* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
+ is called again.
+
+ Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing()
+ to access it, don't access it directly. */
+ _Py_atomic_address _finalizing;
+
+ struct pyinterpreters {
+ PyThread_type_lock mutex;
+ PyInterpreterState *head;
+ PyInterpreterState *main;
+ /* _next_interp_id is an auto-numbered sequence of small
+ integers. It gets initialized in _PyInterpreterState_Init(),
+ which is called in Py_Initialize(), and used in
+ PyInterpreterState_New(). A negative interpreter ID
+ indicates an error occurred. The main interpreter will
+ always have an ID of 0. Overflow results in a RuntimeError.
+ If that becomes a problem later then we can adjust, e.g. by
+ using a Python int. */
+ int64_t next_id;
+ } interpreters;
+ // XXX Remove this field once we have a tp_* slot.
+ struct _xidregistry {
+ PyThread_type_lock mutex;
+ struct _xidregitem *head;
+ } xidregistry;
+
+ unsigned long main_thread;
+
+#define NEXITFUNCS 32
+ void (*exitfuncs[NEXITFUNCS])(void);
+ int nexitfuncs;
+
+ struct _ceval_runtime_state ceval;
+ struct _gilstate_runtime_state gilstate;
+
+ PyPreConfig preconfig;
+
+ Py_OpenCodeHookFunction open_code_hook;
+ void *open_code_userdata;
+ _Py_AuditHookEntry *audit_hook_head;
+
+ // XXX Consolidate globals found via the check-c-globals script.
+} _PyRuntimeState;
+
+#define _PyRuntimeState_INIT \
+ {.preinitialized = 0, .core_initialized = 0, .initialized = 0}
+/* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
+
+
+PyAPI_DATA(_PyRuntimeState) _PyRuntime;
+
+PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
+PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
+
+PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
+
+
+/* Initialize _PyRuntimeState.
+ Return NULL on success, or return an error message on failure. */
+PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
+
+PyAPI_FUNC(void) _PyRuntime_Finalize(void);
+
+
+static inline PyThreadState*
+_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
+ return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
+}
+
+static inline void
+_PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
+ _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_RUNTIME_H */
diff --git a/Makefile.pre.in b/Makefile.pre.in
index ac6c2b1..45e7a83 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -1103,6 +1103,7 @@ PYTHON_HEADERS= \
$(srcdir)/Include/internal/pycore_pylifecycle.h \
$(srcdir)/Include/internal/pycore_pymem.h \
$(srcdir)/Include/internal/pycore_pystate.h \
+ $(srcdir)/Include/internal/pycore_runtime.h \
$(srcdir)/Include/internal/pycore_sysmodule.h \
$(srcdir)/Include/internal/pycore_traceback.h \
$(srcdir)/Include/internal/pycore_tupleobject.h \
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index 95f9e9b..df0eb3a 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -184,6 +184,7 @@
<ClInclude Include="..\Include\internal\pycore_pylifecycle.h" />
<ClInclude Include="..\Include\internal\pycore_pymem.h" />
<ClInclude Include="..\Include\internal\pycore_pystate.h" />
+ <ClInclude Include="..\Include\internal\pycore_runtime.h" />
<ClInclude Include="..\Include\internal\pycore_sysmodule.h" />
<ClInclude Include="..\Include\internal\pycore_traceback.h" />
<ClInclude Include="..\Include\internal\pycore_tupleobject.h" />
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index 32da365..8c605c8 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -255,6 +255,9 @@
<ClInclude Include="..\Include\internal\pycore_pystate.h">
<Filter>Include</Filter>
</ClInclude>
+ <ClInclude Include="..\Include\internal\pycore_runtime.h">
+ <Filter>Include</Filter>
+ </ClInclude>
<ClInclude Include="..\Include\internal\pycore_sysmodule.h">
<Filter>Include</Filter>
</ClInclude>
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 1bc7d77..c2a0781 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1553,7 +1553,7 @@ new_interpreter(PyThreadState **tstate_p)
/* Issue #10915, #15751: The GIL API doesn't work with multiple
interpreters: disable PyGILState_Check(). */
- _PyGILState_check_enabled = 0;
+ runtime->gilstate.check_enabled = 0;
PyInterpreterState *interp = PyInterpreterState_New();
if (interp == NULL) {
diff --git a/Python/pystate.c b/Python/pystate.c
index 19beaf0..3636dc9 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1329,12 +1329,11 @@ PyGILState_GetThisThreadState(void)
int
PyGILState_Check(void)
{
-
- if (!_PyGILState_check_enabled) {
+ struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
+ if (!gilstate->check_enabled) {
return 1;
}
- struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) {
return 1;
}