Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 9752fb7

Browse files
author
Anselm Kruis
committed
Merge branch main into main-slp
2 parents 7a1d7b7 + 50b4857 commit 9752fb7

20 files changed

+144
-104
lines changed

Include/internal/pycore_state.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
extern "C" {
55
#endif
66

7+
#ifndef Py_BUILD_CORE
8+
# error "Py_BUILD_CORE must be defined to include this header"
9+
#endif
10+
711
#include "pystate.h"
812
#include "pythread.h"
913

@@ -219,6 +223,36 @@ PyAPI_FUNC(_PyInitError) _PyRuntime_Initialize(void);
219223
(_PyRuntime.finalizing == tstate)
220224

221225

226+
/* Variable and macro for in-line access to current thread
227+
and interpreter state */
228+
229+
/* Get the current Python thread state.
230+
231+
Efficient macro reading directly the 'gilstate.tstate_current' atomic
232+
variable. The macro is unsafe: it does not check for error and it can
233+
return NULL.
234+
235+
The caller must hold the GIL.
236+
237+
See also PyThreadState_Get() and PyThreadState_GET(). */
238+
#define _PyThreadState_GET() \
239+
((PyThreadState*)_Py_atomic_load_relaxed(&_PyRuntime.gilstate.tstate_current))
240+
241+
/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */
242+
#undef PyThreadState_GET
243+
#define PyThreadState_GET() _PyThreadState_GET()
244+
245+
/* Get the current interpreter state.
246+
247+
The macro is unsafe: it does not check for error and it can return NULL.
248+
249+
The caller must hold the GIL.
250+
251+
See also _PyInterpreterState_Get()
252+
and _PyGILState_GetInterpreterStateUnsafe(). */
253+
#define _PyInterpreterState_GET_UNSAFE() (_PyThreadState_GET()->interp)
254+
255+
222256
/* Other */
223257

224258
PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *);

Include/pystate.h

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -255,15 +255,17 @@ typedef struct _ts {
255255
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
256256
PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *);
257257
PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *);
258+
258259
#if !defined(Py_LIMITED_API)
260+
/* Get the current interpreter state.
261+
262+
Issue a fatal error if there no current Python thread state or no current
263+
interpreter. It cannot return NULL.
264+
265+
The caller must hold the GIL.*/
259266
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
260267
#endif
261-
#ifdef Py_BUILD_CORE
262-
/* Macro which should only be used for performance critical code.
263-
Need "#include "pycore_state.h". See also _PyInterpreterState_Get()
264-
and _PyGILState_GetInterpreterStateUnsafe(). */
265-
# define _PyInterpreterState_GET_UNSAFE() (PyThreadState_GET()->interp)
266-
#endif
268+
267269
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
268270
/* New in 3.7 */
269271
PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *);
@@ -296,11 +298,27 @@ PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
296298
PyAPI_FUNC(void) _PyGILState_Reinit(void);
297299
#endif /* !Py_LIMITED_API */
298300

299-
/* Return the current thread state. The global interpreter lock must be held.
300-
* When the current thread state is NULL, this issues a fatal error (so that
301-
* the caller needn't check for NULL). */
301+
/* Get the current thread state.
302+
303+
When the current thread state is NULL, this issues a fatal error (so that
304+
the caller needn't check for NULL).
305+
306+
The caller must hold the GIL.
307+
308+
See also PyThreadState_GET() and _PyThreadState_GET(). */
302309
PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void);
303310

311+
/* Get the current Python thread state.
312+
313+
Macro using PyThreadState_Get() or _PyThreadState_GET() depending if
314+
pycore_state.h is included or not (this header redefines the macro).
315+
316+
If PyThreadState_Get() is used, issue a fatal error if the current thread
317+
state is NULL.
318+
319+
See also PyThreadState_Get() and _PyThreadState_GET(). */
320+
#define PyThreadState_GET() PyThreadState_Get()
321+
304322
#ifndef Py_LIMITED_API
305323
/* Similar to PyThreadState_Get(), but don't issue a fatal error
306324
* if it is NULL. */
@@ -311,18 +329,6 @@ PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *);
311329
PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void);
312330
PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *);
313331

314-
315-
/* Variable and macro for in-line access to current thread state */
316-
317-
/* Assuming the current thread holds the GIL, this is the
318-
PyThreadState for the current thread. */
319-
#ifdef Py_BUILD_CORE
320-
# define PyThreadState_GET() \
321-
((PyThreadState*)_Py_atomic_load_relaxed(&_PyRuntime.gilstate.tstate_current))
322-
#else
323-
# define PyThreadState_GET() PyThreadState_Get()
324-
#endif
325-
326332
typedef
327333
enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
328334
PyGILState_STATE;
@@ -376,11 +382,11 @@ PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void);
376382
The function returns 1 if _PyGILState_check_enabled is non-zero. */
377383
PyAPI_FUNC(int) PyGILState_Check(void);
378384

379-
/* Unsafe function to get the single PyInterpreterState used by this process'
380-
GILState implementation.
385+
/* Get the single PyInterpreterState used by this process' GILState
386+
implementation.
381387
382-
Return NULL before _PyGILState_Init() is called and after _PyGILState_Fini()
383-
is called.
388+
This function doesn't check for error. Return NULL before _PyGILState_Init()
389+
is called and after _PyGILState_Fini() is called.
384390
385391
See also _PyInterpreterState_Get() and _PyInterpreterState_GET_UNSAFE(). */
386392
PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);

Modules/_testcapimodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4160,7 +4160,7 @@ test_PyTime_AsMicroseconds(PyObject *self, PyObject *args)
41604160
static PyObject*
41614161
get_recursion_depth(PyObject *self, PyObject *args)
41624162
{
4163-
PyThreadState *tstate = PyThreadState_GET();
4163+
PyThreadState *tstate = PyThreadState_Get();
41644164

41654165
/* subtract one to ignore the frame of the get_recursion_depth() call */
41664166
return PyLong_FromLong(tstate->recursion_depth - 1);

Objects/call.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ function_code_fastcall(PyCodeObject *co, PyObject *const *args, Py_ssize_t nargs
328328
{
329329
STACKLESS_GETARG();
330330
PyFrameObject *f;
331-
PyThreadState *tstate = PyThreadState_GET();
331+
PyThreadState *tstate = _PyThreadState_GET();
332332
PyObject **fastlocals;
333333
Py_ssize_t i;
334334
PyObject *result;

Objects/dictobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,9 +1314,9 @@ PyDict_GetItem(PyObject *op, PyObject *key)
13141314
/* We can arrive here with a NULL tstate during initialization: try
13151315
running "python -Wi" for an example related to string interning.
13161316
Let's just hope that no exception occurs then... This must be
1317-
PyThreadState_GET() and not PyThreadState_Get() because the latter
1317+
_PyThreadState_GET() and not PyThreadState_Get() because the latter
13181318
abort Python if tstate is NULL. */
1319-
tstate = PyThreadState_GET();
1319+
tstate = _PyThreadState_GET();
13201320
if (tstate != NULL && tstate->curexc_type != NULL) {
13211321
/* preserve the existing exception */
13221322
PyObject *err_type, *err_value, *err_tb;

Objects/genobject.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, int exc, int closing, PyObject * o
186186
STACKLESS_GETARG();
187187
PyFrameObject *stopframe;
188188
#endif
189-
PyThreadState *tstate = PyThreadState_GET();
189+
PyThreadState *tstate = _PyThreadState_GET();
190190
PyFrameObject *f = gen->gi_frame;
191191
PyObject *result;
192192

@@ -1329,7 +1329,7 @@ PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
13291329
return NULL;
13301330
}
13311331

1332-
PyThreadState *tstate = PyThreadState_GET();
1332+
PyThreadState *tstate = _PyThreadState_GET();
13331333
int origin_depth = tstate->coroutine_origin_tracking_depth;
13341334

13351335
if (origin_depth == 0) {
@@ -1439,7 +1439,7 @@ async_gen_init_hooks(PyAsyncGenObject *o)
14391439

14401440
o->ag_hooks_inited = 1;
14411441

1442-
tstate = PyThreadState_GET();
1442+
tstate = _PyThreadState_GET();
14431443

14441444
finalizer = tstate->async_gen_finalizer;
14451445
if (finalizer) {

Objects/object.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,7 +2139,7 @@ _PyTrash_deposit_object(PyObject *op)
21392139
void
21402140
_PyTrash_thread_deposit_object(PyObject *op)
21412141
{
2142-
PyThreadState *tstate = PyThreadState_GET();
2142+
PyThreadState *tstate = _PyThreadState_GET();
21432143
_PyObject_ASSERT(op, PyObject_IS_GC(op));
21442144
_PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op));
21452145
_PyObject_ASSERT(op, op->ob_refcnt == 0);
@@ -2177,7 +2177,7 @@ _PyTrash_destroy_chain(void)
21772177
void
21782178
_PyTrash_thread_destroy_chain(void)
21792179
{
2180-
PyThreadState *tstate = PyThreadState_GET();
2180+
PyThreadState *tstate = _PyThreadState_GET();
21812181
/* We need to increase trash_delete_nesting here, otherwise,
21822182
_PyTrash_thread_destroy_chain will be called recursively
21832183
and then possibly crash. An example that may crash without

Objects/odictobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,7 @@ static PyGetSetDef odict_getset[] = {
13551355
static void
13561356
odict_dealloc(PyODictObject *self)
13571357
{
1358-
PyThreadState *tstate = PyThreadState_GET();
1358+
PyThreadState *tstate = _PyThreadState_GET();
13591359

13601360
PyObject_GC_UnTrack(self);
13611361
Py_TRASHCAN_SAFE_BEGIN(self)

Objects/typeobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ subtype_dealloc(PyObject *self)
11371137
{
11381138
PyTypeObject *type, *base;
11391139
destructor basedealloc;
1140-
PyThreadState *tstate = PyThreadState_GET();
1140+
PyThreadState *tstate = _PyThreadState_GET();
11411141
int has_finalizer;
11421142

11431143
/* Extract the type; we expect it to be a heap type */
@@ -7994,7 +7994,7 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)
79947994
PyFrameObject *f;
79957995
PyCodeObject *co;
79967996
Py_ssize_t i, n;
7997-
f = PyThreadState_GET()->frame;
7997+
f = _PyThreadState_GET()->frame;
79987998
if (f == NULL) {
79997999
PyErr_SetString(PyExc_RuntimeError,
80008000
"super(): no current frame");

Parser/myreadline.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
301301
char *rv, *res;
302302
size_t len;
303303

304-
if (_PyOS_ReadlineTState == PyThreadState_GET()) {
304+
if (_PyOS_ReadlineTState == _PyThreadState_GET()) {
305305
PyErr_SetString(PyExc_RuntimeError,
306306
"can't re-enter readline");
307307
return NULL;
@@ -316,7 +316,7 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
316316
_PyOS_ReadlineLock = PyThread_allocate_lock();
317317
}
318318

319-
_PyOS_ReadlineTState = PyThreadState_GET();
319+
_PyOS_ReadlineTState = _PyThreadState_GET();
320320
Py_BEGIN_ALLOW_THREADS
321321
PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
322322

Python/_warnings.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,9 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
692692
}
693693
/* fallback to the state frame */
694694
if (f == NULL)
695-
f = PyThreadState_GET()->frame;
695+
f = _PyThreadState_GET()->frame;
696696
#else
697-
PyFrameObject *f = PyThreadState_GET()->frame;
697+
PyFrameObject *f = _PyThreadState_GET()->frame;
698698
#endif
699699
// Stack level comparisons to Python code is off by one as there is no
700700
// warnings-related stack level to avoid.

0 commit comments

Comments
 (0)