[3.14] gh-143057: avoid locking in tracemalloc C-APIs when it is not enabled (GH-143065) (#143071)

gh-143057: avoid locking in `tracemalloc` C-APIs when it is not enabled (GH-143065)
(cherry picked from commit e728b006de)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Miss Islington (bot) 2025-12-22 17:04:24 +01:00 committed by GitHub
parent 6a3b861cb2
commit 98f6db7e82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 3 deletions

View file

@ -21,7 +21,10 @@ struct _PyTraceMalloc_Config {
} initialized;
/* Is tracemalloc tracing memory allocations?
Variable protected by the TABLES_LOCK(). */
Variable protected by the TABLES_LOCK() and stored atomically.
Atomic store is used so that it can read without locking for the
general case of checking if tracemalloc is enabled.
*/
int tracing;
/* limit of the number of frames in a traceback, 1 by default.

View file

@ -0,0 +1 @@
Avoid locking in :c:func:`PyTraceMalloc_Track` and :c:func:`PyTraceMalloc_Untrack` when :mod:`tracemalloc` is not enabled.

View file

@ -840,7 +840,7 @@ _PyTraceMalloc_Start(int max_nframe)
/* everything is ready: start tracing Python memory allocations */
TABLES_LOCK();
tracemalloc_config.tracing = 1;
_Py_atomic_store_int_relaxed(&tracemalloc_config.tracing, 1);
TABLES_UNLOCK();
return 0;
@ -857,7 +857,7 @@ _PyTraceMalloc_Stop(void)
}
/* stop tracing Python memory allocations */
tracemalloc_config.tracing = 0;
_Py_atomic_store_int_relaxed(&tracemalloc_config.tracing, 0);
/* unregister the hook on memory allocators */
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
@ -1197,6 +1197,10 @@ int
PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
size_t size)
{
if (_Py_atomic_load_int_relaxed(&tracemalloc_config.tracing) == 0) {
/* tracemalloc is not tracing: do nothing */
return -2;
}
PyGILState_STATE gil_state = PyGILState_Ensure();
TABLES_LOCK();
@ -1218,6 +1222,11 @@ PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
int
PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
{
if (_Py_atomic_load_int_relaxed(&tracemalloc_config.tracing) == 0) {
/* tracemalloc is not tracing: do nothing */
return -2;
}
TABLES_LOCK();
int result;