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

22612362

typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);

@@ -203,13 +242,16 @@ PyAPI_FUNC(_PyInitError) _PyRuntime_Initialize(void);

203242204243

PyAPI_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);

242283

PyAPI_FUNC(void) _PyThreadState_Init(

243284

_PyRuntimeState *runtime,

244285

PyThreadState *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);

246293247294

PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *runtime);

248295

PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);