Skip to content

Commit

Permalink
Use atomic exchange in Py_SETREF
Browse files Browse the repository at this point in the history
  • Loading branch information
DinoV committed Mar 11, 2024
1 parent 872c071 commit f5892e7
Showing 1 changed file with 36 additions and 16 deletions.
52 changes: 36 additions & 16 deletions Include/cpython/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,23 +321,43 @@ PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
* The memcpy() implementation does not emit a compiler warning if 'src' has
* not the same type than 'src': any pointer type is accepted for 'src'.
*/
#ifdef _Py_TYPEOF
#define Py_SETREF(dst, src) \
do { \
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
_Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
*_tmp_dst_ptr = (src); \
Py_DECREF(_tmp_old_dst); \
} while (0)
#ifdef Py_GIL_DISABLED
#ifdef _Py_TYPEOF
#define Py_SETREF(dst, src) \
do { \
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
_Py_TYPEOF(dst) _tmp_old_dst = (_Py_TYPEOF(src))_Py_atomic_exchange_ptr(\
_tmp_dst_ptr, src); \
Py_DECREF(_tmp_old_dst); \
} while (0)
#else
#define Py_SETREF(dst, src) \
do { \
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
PyObject *_tmp_src = _PyObject_CAST(src); \
PyObject *_tmp_old_dst = _Py_atomic_exchange_ptr(_tmp_dst_ptr, _tmp_src); \
Py_DECREF(_tmp_old_dst); \
} while (0)
#endif
#else
#define Py_SETREF(dst, src) \
do { \
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \
PyObject *_tmp_src = _PyObject_CAST(src); \
memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \
Py_DECREF(_tmp_old_dst); \
} while (0)
#ifdef _Py_TYPEOF
#define Py_SETREF(dst, src) \
do { \
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
_Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
*_tmp_dst_ptr = (src); \
Py_DECREF(_tmp_old_dst); \
} while (0)
#else
#define Py_SETREF(dst, src) \
do { \
PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \
PyObject *_tmp_src = _PyObject_CAST(src); \
memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \
Py_DECREF(_tmp_old_dst); \
} while (0)
#endif
#endif

/* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of
Expand Down

0 comments on commit f5892e7

Please sign in to comment.