Skip to content

Commit e728b00

Browse files
gh-143057: avoid locking in tracemalloc C-APIs when it is not enabled (#143065)
1 parent 9ded3dd commit e728b00

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

Include/internal/pycore_tracemalloc.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ struct _PyTraceMalloc_Config {
2121
} initialized;
2222

2323
/* Is tracemalloc tracing memory allocations?
24-
Variable protected by the TABLES_LOCK(). */
24+
Variable protected by the TABLES_LOCK() and stored atomically.
25+
Atomic store is used so that it can read without locking for the
26+
general case of checking if tracemalloc is enabled.
27+
*/
2528
int tracing;
2629

2730
/* limit of the number of frames in a traceback, 1 by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Avoid locking in :c:func:`PyTraceMalloc_Track` and :c:func:`PyTraceMalloc_Untrack` when :mod:`tracemalloc` is not enabled.

Python/tracemalloc.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ _PyTraceMalloc_Start(int max_nframe)
850850

851851
/* everything is ready: start tracing Python memory allocations */
852852
TABLES_LOCK();
853-
tracemalloc_config.tracing = 1;
853+
_Py_atomic_store_int_relaxed(&tracemalloc_config.tracing, 1);
854854
TABLES_UNLOCK();
855855

856856
return 0;
@@ -867,7 +867,7 @@ _PyTraceMalloc_Stop(void)
867867
}
868868

869869
/* stop tracing Python memory allocations */
870-
tracemalloc_config.tracing = 0;
870+
_Py_atomic_store_int_relaxed(&tracemalloc_config.tracing, 0);
871871

872872
/* unregister the hook on memory allocators */
873873
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
@@ -1207,6 +1207,10 @@ int
12071207
PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
12081208
size_t size)
12091209
{
1210+
if (_Py_atomic_load_int_relaxed(&tracemalloc_config.tracing) == 0) {
1211+
/* tracemalloc is not tracing: do nothing */
1212+
return -2;
1213+
}
12101214
PyGILState_STATE gil_state = PyGILState_Ensure();
12111215
TABLES_LOCK();
12121216

@@ -1228,6 +1232,11 @@ PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
12281232
int
12291233
PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
12301234
{
1235+
if (_Py_atomic_load_int_relaxed(&tracemalloc_config.tracing) == 0) {
1236+
/* tracemalloc is not tracing: do nothing */
1237+
return -2;
1238+
}
1239+
12311240
TABLES_LOCK();
12321241

12331242
int result;

0 commit comments

Comments
 (0)