Skip to content

Commit 1c4cbdf

Browse files
authored
bpo-40268: Add pycore_runtime.h header file (GH-19493)
Move PyRuntimeState from pycore_pystate.h to pycore_runtime.h. Remove _PyGILState_check_enabled macro: access directly _PyRuntime.gilstate.check_enabled.
1 parent 0135598 commit 1c4cbdf

File tree

7 files changed

+152
-125
lines changed

7 files changed

+152
-125
lines changed

Include/internal/pycore_pystate.h

+1-121
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern "C" {
1111
#include "pycore_gil.h" /* struct _gil_runtime_state */
1212
#include "pycore_pymem.h" /* struct _gc_runtime_state */
1313
#include "pycore_warnings.h" /* struct _warnings_runtime_state */
14+
#include "pycore_runtime.h" /* PyRuntimestate */
1415

1516

1617
/* ceval state */
@@ -32,15 +33,6 @@ struct _pending_calls {
3233
int last;
3334
};
3435

35-
struct _ceval_runtime_state {
36-
int recursion_limit;
37-
/* Request for dropping the GIL */
38-
_Py_atomic_int gil_drop_request;
39-
/* Request for checking signals. */
40-
_Py_atomic_int signals_pending;
41-
struct _gil_runtime_state gil;
42-
};
43-
4436
struct _ceval_state {
4537
/* Records whether tracing is on for any thread. Counts the number
4638
of threads for which tstate->c_tracefunc is non-NULL, so if the
@@ -176,118 +168,6 @@ struct _xidregitem {
176168
struct _xidregitem *next;
177169
};
178170

179-
/* runtime audit hook state */
180-
181-
typedef struct _Py_AuditHookEntry {
182-
struct _Py_AuditHookEntry *next;
183-
Py_AuditHookFunction hookCFunction;
184-
void *userData;
185-
} _Py_AuditHookEntry;
186-
187-
/* GIL state */
188-
189-
struct _gilstate_runtime_state {
190-
int check_enabled;
191-
/* Assuming the current thread holds the GIL, this is the
192-
PyThreadState for the current thread. */
193-
_Py_atomic_address tstate_current;
194-
/* The single PyInterpreterState used by this process'
195-
GILState implementation
196-
*/
197-
/* TODO: Given interp_main, it may be possible to kill this ref */
198-
PyInterpreterState *autoInterpreterState;
199-
Py_tss_t autoTSSkey;
200-
};
201-
202-
/* Issue #26558: Flag to disable PyGILState_Check().
203-
If set to non-zero, PyGILState_Check() always return 1. */
204-
#define _PyGILState_check_enabled _PyRuntime.gilstate.check_enabled
205-
206-
207-
/* Full Python runtime state */
208-
209-
typedef struct pyruntimestate {
210-
/* Is running Py_PreInitialize()? */
211-
int preinitializing;
212-
213-
/* Is Python preinitialized? Set to 1 by Py_PreInitialize() */
214-
int preinitialized;
215-
216-
/* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
217-
int core_initialized;
218-
219-
/* Is Python fully initialized? Set to 1 by Py_Initialize() */
220-
int initialized;
221-
222-
/* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
223-
is called again.
224-
225-
Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing()
226-
to access it, don't access it directly. */
227-
_Py_atomic_address _finalizing;
228-
229-
struct pyinterpreters {
230-
PyThread_type_lock mutex;
231-
PyInterpreterState *head;
232-
PyInterpreterState *main;
233-
/* _next_interp_id is an auto-numbered sequence of small
234-
integers. It gets initialized in _PyInterpreterState_Init(),
235-
which is called in Py_Initialize(), and used in
236-
PyInterpreterState_New(). A negative interpreter ID
237-
indicates an error occurred. The main interpreter will
238-
always have an ID of 0. Overflow results in a RuntimeError.
239-
If that becomes a problem later then we can adjust, e.g. by
240-
using a Python int. */
241-
int64_t next_id;
242-
} interpreters;
243-
// XXX Remove this field once we have a tp_* slot.
244-
struct _xidregistry {
245-
PyThread_type_lock mutex;
246-
struct _xidregitem *head;
247-
} xidregistry;
248-
249-
unsigned long main_thread;
250-
251-
#define NEXITFUNCS 32
252-
void (*exitfuncs[NEXITFUNCS])(void);
253-
int nexitfuncs;
254-
255-
struct _ceval_runtime_state ceval;
256-
struct _gilstate_runtime_state gilstate;
257-
258-
PyPreConfig preconfig;
259-
260-
Py_OpenCodeHookFunction open_code_hook;
261-
void *open_code_userdata;
262-
_Py_AuditHookEntry *audit_hook_head;
263-
264-
// XXX Consolidate globals found via the check-c-globals script.
265-
} _PyRuntimeState;
266-
267-
#define _PyRuntimeState_INIT \
268-
{.preinitialized = 0, .core_initialized = 0, .initialized = 0}
269-
/* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
270-
271-
PyAPI_DATA(_PyRuntimeState) _PyRuntime;
272-
PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
273-
PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
274-
PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
275-
276-
/* Initialize _PyRuntimeState.
277-
Return NULL on success, or return an error message on failure. */
278-
PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
279-
280-
PyAPI_FUNC(void) _PyRuntime_Finalize(void);
281-
282-
static inline PyThreadState*
283-
_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
284-
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
285-
}
286-
287-
static inline void
288-
_PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
289-
_Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
290-
}
291171

292172
/* Check if the current thread is the main thread.
293173
Use _Py_IsMainInterpreter() to check if it's the main interpreter. */

Include/internal/pycore_runtime.h

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#ifndef Py_INTERNAL_RUNTIME_H
2+
#define Py_INTERNAL_RUNTIME_H
3+
#ifdef __cplusplus
4+
extern "C" {
5+
#endif
6+
7+
#ifndef Py_BUILD_CORE
8+
# error "this header requires Py_BUILD_CORE define"
9+
#endif
10+
11+
#include "pycore_atomic.h" /* _Py_atomic_address */
12+
#include "pycore_gil.h" // struct _gil_runtime_state
13+
14+
/* ceval state */
15+
16+
struct _ceval_runtime_state {
17+
int recursion_limit;
18+
/* Request for dropping the GIL */
19+
_Py_atomic_int gil_drop_request;
20+
/* Request for checking signals. */
21+
_Py_atomic_int signals_pending;
22+
struct _gil_runtime_state gil;
23+
};
24+
25+
/* GIL state */
26+
27+
struct _gilstate_runtime_state {
28+
/* bpo-26558: Flag to disable PyGILState_Check().
29+
If set to non-zero, PyGILState_Check() always return 1. */
30+
int check_enabled;
31+
/* Assuming the current thread holds the GIL, this is the
32+
PyThreadState for the current thread. */
33+
_Py_atomic_address tstate_current;
34+
/* The single PyInterpreterState used by this process'
35+
GILState implementation
36+
*/
37+
/* TODO: Given interp_main, it may be possible to kill this ref */
38+
PyInterpreterState *autoInterpreterState;
39+
Py_tss_t autoTSSkey;
40+
};
41+
42+
/* Runtime audit hook state */
43+
44+
typedef struct _Py_AuditHookEntry {
45+
struct _Py_AuditHookEntry *next;
46+
Py_AuditHookFunction hookCFunction;
47+
void *userData;
48+
} _Py_AuditHookEntry;
49+
50+
/* Full Python runtime state */
51+
52+
typedef struct pyruntimestate {
53+
/* Is running Py_PreInitialize()? */
54+
int preinitializing;
55+
56+
/* Is Python preinitialized? Set to 1 by Py_PreInitialize() */
57+
int preinitialized;
58+
59+
/* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
60+
int core_initialized;
61+
62+
/* Is Python fully initialized? Set to 1 by Py_Initialize() */
63+
int initialized;
64+
65+
/* Set by Py_FinalizeEx(). Only reset to NULL if Py_Initialize()
66+
is called again.
67+
68+
Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing()
69+
to access it, don't access it directly. */
70+
_Py_atomic_address _finalizing;
71+
72+
struct pyinterpreters {
73+
PyThread_type_lock mutex;
74+
PyInterpreterState *head;
75+
PyInterpreterState *main;
76+
/* _next_interp_id is an auto-numbered sequence of small
77+
integers. It gets initialized in _PyInterpreterState_Init(),
78+
which is called in Py_Initialize(), and used in
79+
PyInterpreterState_New(). A negative interpreter ID
80+
indicates an error occurred. The main interpreter will
81+
always have an ID of 0. Overflow results in a RuntimeError.
82+
If that becomes a problem later then we can adjust, e.g. by
83+
using a Python int. */
84+
int64_t next_id;
85+
} interpreters;
86+
// XXX Remove this field once we have a tp_* slot.
87+
struct _xidregistry {
88+
PyThread_type_lock mutex;
89+
struct _xidregitem *head;
90+
} xidregistry;
91+
92+
unsigned long main_thread;
93+
94+
#define NEXITFUNCS 32
95+
void (*exitfuncs[NEXITFUNCS])(void);
96+
int nexitfuncs;
97+
98+
struct _ceval_runtime_state ceval;
99+
struct _gilstate_runtime_state gilstate;
100+
101+
PyPreConfig preconfig;
102+
103+
Py_OpenCodeHookFunction open_code_hook;
104+
void *open_code_userdata;
105+
_Py_AuditHookEntry *audit_hook_head;
106+
107+
// XXX Consolidate globals found via the check-c-globals script.
108+
} _PyRuntimeState;
109+
110+
#define _PyRuntimeState_INIT \
111+
{.preinitialized = 0, .core_initialized = 0, .initialized = 0}
112+
/* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
113+
114+
115+
PyAPI_DATA(_PyRuntimeState) _PyRuntime;
116+
117+
PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
118+
PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
119+
120+
PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
121+
122+
123+
/* Initialize _PyRuntimeState.
124+
Return NULL on success, or return an error message on failure. */
125+
PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
126+
127+
PyAPI_FUNC(void) _PyRuntime_Finalize(void);
128+
129+
130+
static inline PyThreadState*
131+
_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
132+
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
133+
}
134+
135+
static inline void
136+
_PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
137+
_Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
138+
}
139+
140+
#ifdef __cplusplus
141+
}
142+
#endif
143+
#endif /* !Py_INTERNAL_RUNTIME_H */

Makefile.pre.in

+1
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,7 @@ PYTHON_HEADERS= \
11031103
$(srcdir)/Include/internal/pycore_pylifecycle.h \
11041104
$(srcdir)/Include/internal/pycore_pymem.h \
11051105
$(srcdir)/Include/internal/pycore_pystate.h \
1106+
$(srcdir)/Include/internal/pycore_runtime.h \
11061107
$(srcdir)/Include/internal/pycore_sysmodule.h \
11071108
$(srcdir)/Include/internal/pycore_traceback.h \
11081109
$(srcdir)/Include/internal/pycore_tupleobject.h \

PCbuild/pythoncore.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@
184184
<ClInclude Include="..\Include\internal\pycore_pylifecycle.h" />
185185
<ClInclude Include="..\Include\internal\pycore_pymem.h" />
186186
<ClInclude Include="..\Include\internal\pycore_pystate.h" />
187+
<ClInclude Include="..\Include\internal\pycore_runtime.h" />
187188
<ClInclude Include="..\Include\internal\pycore_sysmodule.h" />
188189
<ClInclude Include="..\Include\internal\pycore_traceback.h" />
189190
<ClInclude Include="..\Include\internal\pycore_tupleobject.h" />

PCbuild/pythoncore.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@
255255
<ClInclude Include="..\Include\internal\pycore_pystate.h">
256256
<Filter>Include</Filter>
257257
</ClInclude>
258+
<ClInclude Include="..\Include\internal\pycore_runtime.h">
259+
<Filter>Include</Filter>
260+
</ClInclude>
258261
<ClInclude Include="..\Include\internal\pycore_sysmodule.h">
259262
<Filter>Include</Filter>
260263
</ClInclude>

Python/pylifecycle.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@ new_interpreter(PyThreadState **tstate_p)
15531553

15541554
/* Issue #10915, #15751: The GIL API doesn't work with multiple
15551555
interpreters: disable PyGILState_Check(). */
1556-
_PyGILState_check_enabled = 0;
1556+
runtime->gilstate.check_enabled = 0;
15571557

15581558
PyInterpreterState *interp = PyInterpreterState_New();
15591559
if (interp == NULL) {

Python/pystate.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -1329,12 +1329,11 @@ PyGILState_GetThisThreadState(void)
13291329
int
13301330
PyGILState_Check(void)
13311331
{
1332-
1333-
if (!_PyGILState_check_enabled) {
1332+
struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
1333+
if (!gilstate->check_enabled) {
13341334
return 1;
13351335
}
13361336

1337-
struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
13381337
if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) {
13391338
return 1;
13401339
}

0 commit comments

Comments
 (0)