bpo-36710: Add 'ceval' local variable to ceval.c (GH-12934) · python/cpython@09532fe
@@ -12,12 +12,51 @@ extern "C" {
1212#include "pystate.h"
1313#include "pythread.h"
141415-#include "pycore_ceval.h"
15+#include "pycore_gil.h" /* _gil_runtime_state */
1616#include "pycore_pathconfig.h"
1717#include "pycore_pymem.h"
1818#include "pycore_warnings.h"
1919202021+/* ceval state */
22+23+struct _pending_calls {
24+int finishing;
25+PyThread_type_lock lock;
26+/* Request for running pending calls. */
27+_Py_atomic_int calls_to_do;
28+/* Request for looking at the `async_exc` field of the current
29+ thread state.
30+ Guarded by the GIL. */
31+int async_exc;
32+#define NPENDINGCALLS 32
33+struct {
34+int (*func)(void *);
35+void *arg;
36+ } calls[NPENDINGCALLS];
37+int first;
38+int last;
39+};
40+41+struct _ceval_runtime_state {
42+int recursion_limit;
43+/* Records whether tracing is on for any thread. Counts the number
44+ of threads for which tstate->c_tracefunc is non-NULL, so if the
45+ value is 0, we know we don't have to check this thread's
46+ c_tracefunc. This speeds up the if statement in
47+ PyEval_EvalFrameEx() after fast_next_opcode. */
48+int tracing_possible;
49+/* This single variable consolidates all requests to break out of
50+ the fast path in the eval loop. */
51+_Py_atomic_int eval_breaker;
52+/* Request for dropping the GIL */
53+_Py_atomic_int gil_drop_request;
54+struct _pending_calls pending;
55+/* Request for checking signals. */
56+_Py_atomic_int signals_pending;
57+struct _gil_runtime_state gil;
58+};
59+2160/* interpreter state */
22612362typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
@@ -203,13 +242,16 @@ PyAPI_FUNC(_PyInitError) _PyRuntime_Initialize(void);
203242204243PyAPI_FUNC(void) _PyRuntime_Finalize(void);
205244206-#define _Py_CURRENTLY_FINALIZING(tstate) \
207- (_PyRuntime.finalizing == tstate)
245+#define _Py_CURRENTLY_FINALIZING(runtime, tstate) \
246+ (runtime->finalizing == tstate)
208247209248210249/* Variable and macro for in-line access to current thread
211250 and interpreter state */
212251252+#define _PyRuntimeState_GetThreadState(runtime) \
253+ ((PyThreadState*)_Py_atomic_load_relaxed(&(runtime)->gilstate.tstate_current))
254+213255/* Get the current Python thread state.
214256215257 Efficient macro reading directly the 'gilstate.tstate_current' atomic
@@ -219,8 +261,7 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void);
219261 The caller must hold the GIL.
220262221263 See also PyThreadState_Get() and PyThreadState_GET(). */
222-#define _PyThreadState_GET() \
223- ((PyThreadState*)_Py_atomic_load_relaxed(&_PyRuntime.gilstate.tstate_current))
264+#define _PyThreadState_GET() _PyRuntimeState_GetThreadState(&_PyRuntime)
224265225266/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */
226267#undef PyThreadState_GET
@@ -242,7 +283,13 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void);
242283PyAPI_FUNC(void) _PyThreadState_Init(
243284_PyRuntimeState *runtime,
244285PyThreadState *tstate);
245-PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
286+PyAPI_FUNC(void) _PyThreadState_DeleteExcept(
287+_PyRuntimeState *runtime,
288+PyThreadState *tstate);
289+290+PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
291+struct _gilstate_runtime_state *gilstate,
292+PyThreadState *newts);
246293247294PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
248295PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);