} 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.
/* 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;
}
/* 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);
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();
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;