]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-143057: avoid locking in `tracemalloc` C-APIs when it is not enabled (GH...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 22 Dec 2025 16:04:24 +0000 (17:04 +0100)
committerGitHub <noreply@github.com>
Mon, 22 Dec 2025 16:04:24 +0000 (16:04 +0000)
gh-143057: avoid locking in `tracemalloc` C-APIs when it is not enabled (GH-143065)
(cherry picked from commit e728b006de984ab11532f5c9cf60c57671ec37ab)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Include/internal/pycore_tracemalloc.h
Misc/NEWS.d/next/Core_and_Builtins/2025-12-22-12-03-09.gh-issue-143057.Majsre.rst [new file with mode: 0644]
Python/tracemalloc.c

index 572e80258763197a805681e9f9a7425afe30f697..41e1c91bee4fde77d2e11d745af640ce5e3e0ad9 100644 (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.
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-22-12-03-09.gh-issue-143057.Majsre.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-22-12-03-09.gh-issue-143057.Majsre.rst
new file mode 100644 (file)
index 0000000..2eac8c1
--- /dev/null
@@ -0,0 +1 @@
+Avoid locking in :c:func:`PyTraceMalloc_Track` and :c:func:`PyTraceMalloc_Untrack` when :mod:`tracemalloc` is not enabled.
index 7066a214f1065bac435ab70fa94026acfa160b9c..8ae12e545761efa4c8347162913375ab90d6068d 100644 (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;