]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-143057: avoid locking in `tracemalloc` C-APIs when it is not enabled (#143065)
authorKumar Aditya <kumaraditya@python.org>
Mon, 22 Dec 2025 15:38:07 +0000 (21:08 +0530)
committerGitHub <noreply@github.com>
Mon, 22 Dec 2025 15:38:07 +0000 (21:08 +0530)
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 693385f9a46d12ca8f8412235562c7ea62af28a9..9974ea3c4143fa6bc3ce97141eea6665849fd2e8 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 20351618721c3ba8990490af80fd63b314334128..cdd96925d1f27a02faef667e4ed311e3d54e7135 100644 (file)
@@ -850,7 +850,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;
@@ -867,7 +867,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);
@@ -1207,6 +1207,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();
 
@@ -1228,6 +1232,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;