@@ -74,21 +74,14 @@ get_legacy_reftotal(void)
7474 interp->object_state.reftotal
7575
7676static inline void
77- reftotal_increment ( PyInterpreterState * interp )
77+ reftotal_add ( PyThreadState * tstate , Py_ssize_t n )
7878{
79- REFTOTAL (interp )++ ;
80- }
81-
82- static inline void
83- reftotal_decrement (PyInterpreterState * interp )
84- {
85- REFTOTAL (interp )-- ;
86- }
87-
88- static inline void
89- reftotal_add (PyInterpreterState * interp , Py_ssize_t n )
90- {
91- REFTOTAL (interp ) += n ;
79+ #ifdef Py_GIL_DISABLED
80+ _PyThreadStateImpl * tstate_impl = (_PyThreadStateImpl * )tstate ;
81+ tstate_impl -> reftotal += n ;
82+ #else
83+ REFTOTAL (tstate -> interp ) += n ;
84+ #endif
9285}
9386
9487static inline Py_ssize_t get_global_reftotal (_PyRuntimeState * );
@@ -118,7 +111,14 @@ get_reftotal(PyInterpreterState *interp)
118111{
119112 /* For a single interpreter, we ignore the legacy _Py_RefTotal,
120113 since we can't determine which interpreter updated it. */
121- return REFTOTAL (interp );
114+ Py_ssize_t total = REFTOTAL (interp );
115+ #ifdef Py_GIL_DISABLED
116+ for (PyThreadState * p = interp -> threads .head ; p != NULL ; p = p -> next ) {
117+ /* This may race with other threads modifications to their reftotal */
118+ total += ((_PyThreadStateImpl * )p )-> reftotal ;
119+ }
120+ #endif
121+ return total ;
122122}
123123
124124static inline Py_ssize_t
@@ -130,7 +130,7 @@ get_global_reftotal(_PyRuntimeState *runtime)
130130 HEAD_LOCK (& _PyRuntime );
131131 PyInterpreterState * interp = PyInterpreterState_Head ();
132132 for (; interp != NULL ; interp = PyInterpreterState_Next (interp )) {
133- total += REFTOTAL (interp );
133+ total += get_reftotal (interp );
134134 }
135135 HEAD_UNLOCK (& _PyRuntime );
136136
@@ -223,32 +223,32 @@ _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op)
223223void
224224_Py_INCREF_IncRefTotal (void )
225225{
226- reftotal_increment ( _PyInterpreterState_GET () );
226+ reftotal_add ( _PyThreadState_GET (), 1 );
227227}
228228
229229/* This is used strictly by Py_DECREF(). */
230230void
231231_Py_DECREF_DecRefTotal (void )
232232{
233- reftotal_decrement ( _PyInterpreterState_GET () );
233+ reftotal_add ( _PyThreadState_GET (), -1 );
234234}
235235
236236void
237- _Py_IncRefTotal (PyInterpreterState * interp )
237+ _Py_IncRefTotal (PyThreadState * tstate )
238238{
239- reftotal_increment ( interp );
239+ reftotal_add ( tstate , 1 );
240240}
241241
242242void
243- _Py_DecRefTotal (PyInterpreterState * interp )
243+ _Py_DecRefTotal (PyThreadState * tstate )
244244{
245- reftotal_decrement ( interp );
245+ reftotal_add ( tstate , -1 );
246246}
247247
248248void
249- _Py_AddRefTotal (PyInterpreterState * interp , Py_ssize_t n )
249+ _Py_AddRefTotal (PyThreadState * tstate , Py_ssize_t n )
250250{
251- reftotal_add (interp , n );
251+ reftotal_add (tstate , n );
252252}
253253
254254/* This includes the legacy total
@@ -268,7 +268,10 @@ _Py_GetLegacyRefTotal(void)
268268Py_ssize_t
269269_PyInterpreterState_GetRefTotal (PyInterpreterState * interp )
270270{
271- return get_reftotal (interp );
271+ HEAD_LOCK (& _PyRuntime );
272+ Py_ssize_t total = get_reftotal (interp );
273+ HEAD_UNLOCK (& _PyRuntime );
274+ return total ;
272275}
273276
274277#endif /* Py_REF_DEBUG */
@@ -346,7 +349,7 @@ _Py_DecRefSharedDebug(PyObject *o, const char *filename, int lineno)
346349
347350 if (should_queue ) {
348351#ifdef Py_REF_DEBUG
349- _Py_IncRefTotal (_PyInterpreterState_GET ());
352+ _Py_IncRefTotal (_PyThreadState_GET ());
350353#endif
351354 _Py_brc_queue_object (o );
352355 }
@@ -406,7 +409,7 @@ _Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra)
406409 & shared , new_shared ));
407410
408411#ifdef Py_REF_DEBUG
409- _Py_AddRefTotal (_PyInterpreterState_GET (), extra );
412+ _Py_AddRefTotal (_PyThreadState_GET (), extra );
410413#endif
411414
412415 _Py_atomic_store_uint32_relaxed (& op -> ob_ref_local , 0 );
@@ -2374,7 +2377,7 @@ void
23742377_Py_NewReference (PyObject * op )
23752378{
23762379#ifdef Py_REF_DEBUG
2377- reftotal_increment ( _PyInterpreterState_GET ());
2380+ _Py_IncRefTotal ( _PyThreadState_GET ());
23782381#endif
23792382 new_reference (op );
23802383}
0 commit comments