Skip to content

Commit 98f6db7

Browse files
[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 e728b00) Co-authored-by: Kumar Aditya <kumaraditya@python.org>
1 parent 6a3b861 commit 98f6db7

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
@@ -840,7 +840,7 @@ _PyTraceMalloc_Start(int max_nframe)
840840

841841
/* everything is ready: start tracing Python memory allocations */
842842
TABLES_LOCK();
843-
tracemalloc_config.tracing = 1;
843+
_Py_atomic_store_int_relaxed(&tracemalloc_config.tracing, 1);
844844
TABLES_UNLOCK();
845845

846846
return 0;
@@ -857,7 +857,7 @@ _PyTraceMalloc_Stop(void)
857857
}
858858

859859
/* stop tracing Python memory allocations */
860-
tracemalloc_config.tracing = 0;
860+
_Py_atomic_store_int_relaxed(&tracemalloc_config.tracing, 0);
861861

862862
/* unregister the hook on memory allocators */
863863
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
@@ -1197,6 +1197,10 @@ int
11971197
PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
11981198
size_t size)
11991199
{
1200+
if (_Py_atomic_load_int_relaxed(&tracemalloc_config.tracing) == 0) {
1201+
/* tracemalloc is not tracing: do nothing */
1202+
return -2;
1203+
}
12001204
PyGILState_STATE gil_state = PyGILState_Ensure();
12011205
TABLES_LOCK();
12021206

@@ -1218,6 +1222,11 @@ PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
12181222
int
12191223
PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
12201224
{
1225+
if (_Py_atomic_load_int_relaxed(&tracemalloc_config.tracing) == 0) {
1226+
/* tracemalloc is not tracing: do nothing */
1227+
return -2;
1228+
}
1229+
12211230
TABLES_LOCK();
12221231

12231232
int result;

0 commit comments

Comments
 (0)