Skip to content

Commit e3d02ca

Browse files
committed
Use relaxed atomic to avoid undefined behavior
1 parent 6bdbad0 commit e3d02ca

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

Objects/object.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ reftotal_add(PyThreadState *tstate, Py_ssize_t n)
7777
{
7878
#ifdef Py_GIL_DISABLED
7979
_PyThreadStateImpl *tstate_impl = (_PyThreadStateImpl *)tstate;
80-
tstate_impl->reftotal += n;
80+
// relaxed store to avoid data race with read in get_reftotal()
81+
Py_ssize_t reftotal = tstate_impl->reftotal + n;
82+
_Py_atomic_store_ssize_relaxed(&tstate_impl->reftotal, reftotal);
8183
#else
8284
REFTOTAL(tstate->interp) += n;
8385
#endif
@@ -114,7 +116,8 @@ get_reftotal(PyInterpreterState *interp)
114116
#ifdef Py_GIL_DISABLED
115117
for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
116118
/* This may race with other threads modifications to their reftotal */
117-
total += ((_PyThreadStateImpl *)p)->reftotal;
119+
_PyThreadStateImpl *tstate_impl = (_PyThreadStateImpl *)p;
120+
total += _Py_atomic_load_ssize_relaxed(&tstate_impl->reftotal);
118121
}
119122
#endif
120123
return total;

0 commit comments

Comments
 (0)