Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Include/internal/pycore_pyatomic_ft_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,23 @@ extern "C" {
#endif

#ifdef Py_GIL_DISABLED
#define FT_ATOMIC_LOAD_PTR(value) _Py_atomic_load_ptr(&value)
#define FT_ATOMIC_LOAD_SSIZE(value) _Py_atomic_load_ssize(&value)
#define FT_ATOMIC_LOAD_SSIZE_RELAXED(value) \
_Py_atomic_load_ssize_relaxed(&value)
#define FT_ATOMIC_STORE_PTR(value, new_value) \
_Py_atomic_store_ptr(&value, new_value)
#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) \
_Py_atomic_store_ptr_relaxed(&value, new_value)
#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) \
_Py_atomic_store_ptr_release(&value, new_value)
#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) \
_Py_atomic_store_ssize_relaxed(&value, new_value)
#else
#define FT_ATOMIC_LOAD_PTR(value) value
#define FT_ATOMIC_LOAD_SSIZE(value) value
#define FT_ATOMIC_LOAD_SSIZE_RELAXED(value) value
#define FT_ATOMIC_STORE_PTR(value, new_value) value = new_value
#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value
#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) value = new_value
#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value
Expand Down
7 changes: 7 additions & 0 deletions Objects/tupleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,13 @@ static inline int
maybe_freelist_push(PyTupleObject *op)
{
#ifdef WITH_FREELISTS
#ifdef Py_GIL_DISABLED
if (_PyObject_GC_IS_SHARED_INLINE((PyObject *) op)) {
// There may still be threads that are concurrently reading from the
// tuple.
return 0;
}
#endif
Comment thread
mpage marked this conversation as resolved.
Outdated
struct _Py_object_freelists *freelists = _Py_object_freelists_GET();
if (Py_SIZE(op) == 0) {
return 0;
Expand Down
23 changes: 11 additions & 12 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Python.h"
#include "pycore_abstract.h" // _PySequence_IterSearch()
#include "pycore_pyatomic_ft_wrappers.h"
#include "pycore_call.h" // _PyObject_VectorcallTstate()
#include "pycore_code.h" // CO_FAST_FREE
#include "pycore_dict.h" // _PyDict_KeysSize()
Expand Down Expand Up @@ -366,15 +367,14 @@ clear_tp_bases(PyTypeObject *self)
static inline PyObject *
lookup_tp_mro(PyTypeObject *self)
{
ASSERT_TYPE_LOCK_HELD();
return self->tp_mro;
return FT_ATOMIC_LOAD_PTR(self->tp_mro);
}

PyObject *
_PyType_GetMRO(PyTypeObject *self)
{
PyObject *mro = lookup_tp_mro(self);
#ifdef Py_GIL_DISABLED
PyObject *mro = _Py_atomic_load_ptr_relaxed(&self->tp_mro);
if (mro == NULL) {
return NULL;
}
Expand All @@ -388,7 +388,7 @@ _PyType_GetMRO(PyTypeObject *self)
END_TYPE_LOCK()
return mro;
#else
return Py_XNewRef(lookup_tp_mro(self));
return Py_XNewRef(mro);
#endif
}

Expand All @@ -404,7 +404,13 @@ set_tp_mro(PyTypeObject *self, PyObject *mro)
/* Other checks are done via set_tp_bases. */
_Py_SetImmortal(mro);
}
self->tp_mro = mro;
#ifdef Py_GIL_DISABLED
if (self->tp_mro != NULL) {
// Allow concurrent reads from PyType_IsSubtype
_PyObject_GC_SET_SHARED_INLINE(self->tp_mro);
}
#endif
FT_ATOMIC_STORE_PTR(self->tp_mro, mro);
}

static inline void
Expand Down Expand Up @@ -2341,14 +2347,7 @@ is_subtype_with_mro(PyObject *a_mro, PyTypeObject *a, PyTypeObject *b)
int
PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
{
#ifdef Py_GIL_DISABLED
PyObject *mro = _PyType_GetMRO(a);
int res = is_subtype_with_mro(mro, a, b);
Py_XDECREF(mro);
return res;
#else
return is_subtype_with_mro(lookup_tp_mro(a), a, b);
#endif
}

/* Routines to do a method lookup in the type without looking in the
Expand Down