Skip to content

Commit bef1bcb

Browse files
committed
Fix a couple bugs related to stats allocation.
Need to allocate in stats_toggle_on_off() if the thread never had stats enabled yet. For zeroing, handle case that struct is not allocated. Remove bogus ts->_status.active check.
1 parent 724b086 commit bef1bcb

File tree

1 file changed

+15
-12
lines changed

1 file changed

+15
-12
lines changed

Python/pystats.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,9 @@ void
534534
stats_zero_thread(_PyThreadStateImpl *tstate)
535535
{
536536
// Zero the thread local stat counters
537-
memset(tstate->pystats_struct, 0, sizeof(PyStats));
537+
if (tstate->pystats_struct) {
538+
memset(tstate->pystats_struct, 0, sizeof(PyStats));
539+
}
538540
}
539541

540542
// merge stats for a single thread into the global structure
@@ -575,7 +577,7 @@ stats_toggle_on_off(PyThreadState *tstate, int on)
575577
FT_ATOMIC_STORE_PTR_RELAXED(interp->pystats_struct, s);
576578
}
577579
if (tstate->interp->pystats_enabled != on) {
578-
FT_ATOMIC_STORE_INT_RELAXED(tstate->interp->pystats_enabled, on);
580+
FT_ATOMIC_STORE_INT_RELAXED(interp->pystats_enabled, on);
579581
changed = true;
580582
}
581583
STATS_UNLOCK(interp);
@@ -584,20 +586,19 @@ stats_toggle_on_off(PyThreadState *tstate, int on)
584586
}
585587
_PyEval_StopTheWorld(interp);
586588
_Py_FOR_EACH_TSTATE_UNLOCKED(interp, ts) {
587-
if (!ts->_status.active) {
588-
continue;
589-
}
590-
PyStats *s;
589+
PyStats *s = NULL;
591590
if (interp->pystats_enabled) {
592591
#ifdef Py_GIL_DISABLED
593-
s = ((_PyThreadStateImpl *)ts)->pystats_struct;
592+
_PyThreadStateImpl *ts_impl = (_PyThreadStateImpl *)ts;
593+
if (ts_impl->pystats_struct == NULL) {
594+
// first activation for this thread, allocate structure
595+
ts_impl->pystats_struct = PyMem_RawCalloc(1, sizeof(PyStats));
596+
}
597+
s = ts_impl->pystats_struct;
594598
#else
595-
s = ((PyThreadState *)tstate)->interp->pystats_struct;
599+
s = ts->interp->pystats_struct;
596600
#endif
597601
}
598-
else {
599-
s = NULL;
600-
}
601602
ts->pystats = s;
602603
}
603604
_PyEval_StartTheWorld(interp);
@@ -622,7 +623,9 @@ stats_zero_all(void)
622623
stats_zero_thread((_PyThreadStateImpl *)ts);
623624
}
624625
#endif
625-
memset(interp->pystats_struct, 0, sizeof(PyStats));
626+
if (interp->pystats_struct) {
627+
memset(interp->pystats_struct, 0, sizeof(PyStats));
628+
}
626629
_PyEval_StartTheWorld(interp);
627630
}
628631

0 commit comments

Comments
 (0)