mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-128679: Redesign tracemalloc locking (#128888)
* Use TABLES_LOCK() to protect 'tracemalloc_config.tracing'. * Hold TABLES_LOCK() longer while accessing tables. * tracemalloc_realloc() and tracemalloc_free() no longer remove the trace on reentrant call. * _PyTraceMalloc_Stop() unregisters _PyTraceMalloc_TraceRef(). * _PyTraceMalloc_GetTraces() sets the reentrant flag. * tracemalloc_clear_traces_unlocked() sets the reentrant flag.
This commit is contained in:
parent
080f444a58
commit
36c5e3bcc2
5 changed files with 302 additions and 364 deletions
|
@ -299,12 +299,6 @@ Py_ssize_t _Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra);
|
|||
extern int _PyType_CheckConsistency(PyTypeObject *type);
|
||||
extern int _PyDict_CheckConsistency(PyObject *mp, int check_content);
|
||||
|
||||
/* Update the Python traceback of an object. This function must be called
|
||||
when a memory block is reused from a free list.
|
||||
|
||||
Internal function called by _Py_NewReference(). */
|
||||
extern int _PyTraceMalloc_TraceRef(PyObject *op, PyRefTracerEvent event, void*);
|
||||
|
||||
// Fast inlined version of PyType_HasFeature()
|
||||
static inline int
|
||||
_PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
|
||||
|
|
|
@ -25,7 +25,7 @@ struct _PyTraceMalloc_Config {
|
|||
} initialized;
|
||||
|
||||
/* Is tracemalloc tracing memory allocations?
|
||||
Variable protected by the GIL */
|
||||
Variable protected by the TABLES_LOCK(). */
|
||||
int tracing;
|
||||
|
||||
/* limit of the number of frames in a traceback, 1 by default.
|
||||
|
@ -85,14 +85,14 @@ struct _tracemalloc_runtime_state {
|
|||
size_t peak_traced_memory;
|
||||
/* Hash table used as a set to intern filenames:
|
||||
PyObject* => PyObject*.
|
||||
Protected by the GIL */
|
||||
Protected by the TABLES_LOCK(). */
|
||||
_Py_hashtable_t *filenames;
|
||||
/* Buffer to store a new traceback in traceback_new().
|
||||
Protected by the GIL. */
|
||||
Protected by the TABLES_LOCK(). */
|
||||
struct tracemalloc_traceback *traceback;
|
||||
/* Hash table used as a set to intern tracebacks:
|
||||
traceback_t* => traceback_t*
|
||||
Protected by the GIL */
|
||||
Protected by the TABLES_LOCK(). */
|
||||
_Py_hashtable_t *tracebacks;
|
||||
/* pointer (void*) => trace (trace_t*).
|
||||
Protected by TABLES_LOCK(). */
|
||||
|
@ -144,7 +144,7 @@ extern PyObject* _PyTraceMalloc_GetTraces(void);
|
|||
extern PyObject* _PyTraceMalloc_GetObjectTraceback(PyObject *obj);
|
||||
|
||||
/* Initialize tracemalloc */
|
||||
extern int _PyTraceMalloc_Init(void);
|
||||
extern PyStatus _PyTraceMalloc_Init(void);
|
||||
|
||||
/* Start tracemalloc */
|
||||
extern int _PyTraceMalloc_Start(int max_nframe);
|
||||
|
|
|
@ -215,18 +215,14 @@ static struct PyModuleDef module_def = {
|
|||
PyMODINIT_FUNC
|
||||
PyInit__tracemalloc(void)
|
||||
{
|
||||
PyObject *m;
|
||||
m = PyModule_Create(&module_def);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
#ifdef Py_GIL_DISABLED
|
||||
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
||||
#endif
|
||||
|
||||
if (_PyTraceMalloc_Init() < 0) {
|
||||
Py_DECREF(m);
|
||||
PyObject *mod = PyModule_Create(&module_def);
|
||||
if (mod == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m;
|
||||
#ifdef Py_GIL_DISABLED
|
||||
PyUnstable_Module_SetGIL(mod, Py_MOD_GIL_NOT_USED);
|
||||
#endif
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
|
|
@ -710,6 +710,11 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
|
|||
return _PyStatus_NO_MEMORY();
|
||||
}
|
||||
|
||||
status = _PyTraceMalloc_Init();
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
PyThreadState *tstate = _PyThreadState_New(interp,
|
||||
_PyThreadState_WHENCE_INIT);
|
||||
if (tstate == NULL) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue