@@ -74,21 +74,14 @@ get_legacy_reftotal(void)
74
74
interp->object_state.reftotal
75
75
76
76
static inline void
77
- reftotal_increment ( PyInterpreterState * interp )
77
+ reftotal_add ( PyThreadState * tstate , Py_ssize_t n )
78
78
{
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
92
85
}
93
86
94
87
static inline Py_ssize_t get_global_reftotal (_PyRuntimeState * );
@@ -118,7 +111,14 @@ get_reftotal(PyInterpreterState *interp)
118
111
{
119
112
/* For a single interpreter, we ignore the legacy _Py_RefTotal,
120
113
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 ;
122
122
}
123
123
124
124
static inline Py_ssize_t
@@ -130,7 +130,7 @@ get_global_reftotal(_PyRuntimeState *runtime)
130
130
HEAD_LOCK (& _PyRuntime );
131
131
PyInterpreterState * interp = PyInterpreterState_Head ();
132
132
for (; interp != NULL ; interp = PyInterpreterState_Next (interp )) {
133
- total += REFTOTAL (interp );
133
+ total += get_reftotal (interp );
134
134
}
135
135
HEAD_UNLOCK (& _PyRuntime );
136
136
@@ -223,32 +223,32 @@ _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op)
223
223
void
224
224
_Py_INCREF_IncRefTotal (void )
225
225
{
226
- reftotal_increment ( _PyInterpreterState_GET () );
226
+ reftotal_add ( _PyThreadState_GET (), 1 );
227
227
}
228
228
229
229
/* This is used strictly by Py_DECREF(). */
230
230
void
231
231
_Py_DECREF_DecRefTotal (void )
232
232
{
233
- reftotal_decrement ( _PyInterpreterState_GET () );
233
+ reftotal_add ( _PyThreadState_GET (), -1 );
234
234
}
235
235
236
236
void
237
- _Py_IncRefTotal (PyInterpreterState * interp )
237
+ _Py_IncRefTotal (PyThreadState * tstate )
238
238
{
239
- reftotal_increment ( interp );
239
+ reftotal_add ( tstate , 1 );
240
240
}
241
241
242
242
void
243
- _Py_DecRefTotal (PyInterpreterState * interp )
243
+ _Py_DecRefTotal (PyThreadState * tstate )
244
244
{
245
- reftotal_decrement ( interp );
245
+ reftotal_add ( tstate , -1 );
246
246
}
247
247
248
248
void
249
- _Py_AddRefTotal (PyInterpreterState * interp , Py_ssize_t n )
249
+ _Py_AddRefTotal (PyThreadState * tstate , Py_ssize_t n )
250
250
{
251
- reftotal_add (interp , n );
251
+ reftotal_add (tstate , n );
252
252
}
253
253
254
254
/* This includes the legacy total
@@ -268,7 +268,10 @@ _Py_GetLegacyRefTotal(void)
268
268
Py_ssize_t
269
269
_PyInterpreterState_GetRefTotal (PyInterpreterState * interp )
270
270
{
271
- return get_reftotal (interp );
271
+ HEAD_LOCK (& _PyRuntime );
272
+ Py_ssize_t total = get_reftotal (interp );
273
+ HEAD_UNLOCK (& _PyRuntime );
274
+ return total ;
272
275
}
273
276
274
277
#endif /* Py_REF_DEBUG */
@@ -346,7 +349,7 @@ _Py_DecRefSharedDebug(PyObject *o, const char *filename, int lineno)
346
349
347
350
if (should_queue ) {
348
351
#ifdef Py_REF_DEBUG
349
- _Py_IncRefTotal (_PyInterpreterState_GET ());
352
+ _Py_IncRefTotal (_PyThreadState_GET ());
350
353
#endif
351
354
_Py_brc_queue_object (o );
352
355
}
@@ -406,7 +409,7 @@ _Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra)
406
409
& shared , new_shared ));
407
410
408
411
#ifdef Py_REF_DEBUG
409
- _Py_AddRefTotal (_PyInterpreterState_GET (), extra );
412
+ _Py_AddRefTotal (_PyThreadState_GET (), extra );
410
413
#endif
411
414
412
415
_Py_atomic_store_uint32_relaxed (& op -> ob_ref_local , 0 );
@@ -2374,7 +2377,7 @@ void
2374
2377
_Py_NewReference (PyObject * op )
2375
2378
{
2376
2379
#ifdef Py_REF_DEBUG
2377
- reftotal_increment ( _PyInterpreterState_GET ());
2380
+ _Py_IncRefTotal ( _PyThreadState_GET ());
2378
2381
#endif
2379
2382
new_reference (op );
2380
2383
}
0 commit comments