Skip to content

Commit 77d8f43

Browse files
committed
Fix free threading.
1 parent 5f702e5 commit 77d8f43

5 files changed

Lines changed: 48 additions & 17 deletions

File tree

Include/internal/pycore_pystate.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,12 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_GetCurrent(void);
113113
114114
See also PyThreadState_Get() and PyThreadState_GetUnchecked(). */
115115

116-
#ifdef Py_DEBUG
116+
static PyThreadState*
117117
// Forcing this to be non-inlined is nice for finding where this is called often.
118-
static Py_NO_INLINE PyThreadState*
118+
#ifdef Py_DEBUG
119+
_Py_MAYBE_UNUSED Py_NO_INLINE
119120
#else
120-
static inline PyThreadState*
121+
inline
121122
#endif
122123
_PyThreadState_GET(void)
123124
{
@@ -211,11 +212,11 @@ _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
211212
212213
See also PyInterpreterState_Get()
213214
and _PyGILState_GetInterpreterStateUnsafe(). */
215+
static _Py_MAYBE_UNUSED PyInterpreterState*
214216
#ifdef Py_DEBUG
215-
// Forcing this to be non-inlined is nice for finding where this is called often.
216-
static Py_NO_INLINE PyInterpreterState*
217+
Py_NO_INLINE
217218
#else
218-
static inline PyInterpreterState*
219+
inline
219220
#endif
220221
_PyInterpreterState_GET(void) {
221222
#ifdef Py_DEBUG

Include/pyport.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,5 +667,13 @@ extern "C" {
667667
# define _Py_STACK_GROWS_DOWN 1
668668
#endif
669669

670+
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
671+
// C23 standard attribute
672+
# define _Py_MAYBE_UNUSED [[maybe_unused]]
673+
#elif _Py__has_attribute(__unused__)
674+
# define _Py_MAYBE_UNUSED __attribute__((__unused__))
675+
#else
676+
# define _Py_MAYBE_UNUSED
677+
#endif
670678

671679
#endif /* Py_PYPORT_H */

Include/refcount.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,17 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
314314
#if !defined(Py_LIMITED_API)
315315
#if defined(Py_GIL_DISABLED)
316316
// Implements Py_DECREF on objects not owned by the current thread.
317-
PyAPI_FUNC(void) _Py_DecRefShared(PyThreadState *, PyObject *);
318-
PyAPI_FUNC(void) _Py_DecRefSharedDebug(PyThreadState *, PyObject *, const char *, int);
317+
PyAPI_FUNC(void) _Py_DecRefShared(PyObject *);
318+
PyAPI_FUNC(void) _Py_DecRefSharedDebug(PyObject *, const char *, int);
319+
PyAPI_FUNC(void) _Py_DecRefSharedTstate(PyThreadState *, PyObject *);
320+
PyAPI_FUNC(void) _Py_DecRefSharedDebugTstate(PyThreadState *, PyObject *, const char *, int);
319321

320322
// Called from Py_DECREF by the owning thread when the local refcount reaches
321323
// zero. The call will deallocate the object if the shared refcount is also
322324
// zero. Otherwise, the thread gives up ownership and merges the reference
323325
// count fields.
324-
PyAPI_FUNC(void) _Py_MergeZeroLocalRefcount(PyThreadState *, PyObject *);
326+
PyAPI_FUNC(void) _Py_MergeZeroLocalRefcount(PyObject *);
327+
PyAPI_FUNC(void) _Py_MergeZeroLocalRefcountTstate(PyThreadState *, PyObject *);
325328
#endif // Py_GIL_DISABLED
326329
#endif // Py_LIMITED_API
327330

@@ -385,7 +388,7 @@ static inline void Py_DECREF(PyObject *op)
385388
}
386389
}
387390
else {
388-
_Py_DecRefShared(_PyThreadState_GET(), op);
391+
_Py_DecRefShared(op);
389392
}
390393
}
391394
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))
@@ -402,11 +405,11 @@ static inline void _Py_DECREF(PyThreadState *tstate, PyObject *op)
402405
local--;
403406
_Py_atomic_store_uint32_relaxed(&op->ob_ref_local, local);
404407
if (local == 0) {
405-
_Py_MergeZeroLocalRefcount(tstate, op);
408+
_Py_MergeZeroLocalRefcountTstate(tstate, op);
406409
}
407410
}
408411
else {
409-
_Py_DecRefShared(tstate, op);
412+
_Py_DecRefSharedTstate(tstate, op);
410413
}
411414
}
412415

Objects/object.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,21 +420,33 @@ _Py_DecRefSharedIsDead(PyObject *o, const char *filename, int lineno)
420420
}
421421

422422
void
423-
_Py_DecRefSharedDebug(PyThreadState *tstate, PyObject *o, const char *filename, int lineno)
423+
_Py_DecRefSharedDebugTstate(PyThreadState *tstate, PyObject *o, const char *filename, int lineno)
424424
{
425425
if (_Py_DecRefSharedIsDead(o, filename, lineno)) {
426-
_Py_Dealloc(tstate, o);
426+
_Py_DeallocTstate(tstate, o);
427427
}
428428
}
429429

430430
void
431-
_Py_DecRefShared(PyThreadState *tstate, PyObject *o)
431+
_Py_DecRefSharedDebug(PyObject *o, const char *filename, int lineno)
432432
{
433-
_Py_DecRefSharedDebug(tstate, o, NULL, 0);
433+
_Py_DecRefSharedDebugTstate(_PyThreadState_GET(), o, filename, lineno);
434434
}
435435

436436
void
437-
_Py_MergeZeroLocalRefcount(PyThreadState *tstate, PyObject *op)
437+
_Py_DecRefSharedTstate(PyThreadState *tstate, PyObject *o)
438+
{
439+
_Py_DecRefSharedDebugTstate(tstate, o, NULL, 0);
440+
}
441+
442+
void
443+
_Py_DecRefShared(PyObject *o)
444+
{
445+
_Py_DecRefSharedTstate(_PyThreadState_GET(), o);
446+
}
447+
448+
void
449+
_Py_MergeZeroLocalRefcountTstate(PyThreadState *tstate, PyObject *op)
438450
{
439451
assert(op->ob_ref_local == 0);
440452

@@ -464,6 +476,12 @@ _Py_MergeZeroLocalRefcount(PyThreadState *tstate, PyObject *op)
464476
}
465477
}
466478

479+
void
480+
_Py_MergeZeroLocalRefcount(PyObject *op)
481+
{
482+
_Py_MergeZeroLocalRefcountTstate(_PyThreadState_GET(), op);
483+
}
484+
467485
Py_ssize_t
468486
_Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra)
469487
{

Python/gc_free_threading.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Cyclic garbage collector implementation for free-threaded build.
22
#include "Python.h"
33
#include "pycore_brc.h" // struct _brc_thread_state
4+
#include "pycore_call.h" // _PyObject_VectorcallTstate()
45
#include "pycore_ceval.h" // _Py_set_eval_breaker_bit()
56
#include "pycore_dict.h" // _PyInlineValuesSize()
67
#include "pycore_frame.h" // FRAME_CLEARED

0 commit comments

Comments
 (0)