Skip to content

Commit 3f867d5

Browse files
kumaraditya303miss-islington
authored andcommitted
gh-155725: Remove PyGILState_Ensure usage from tracemalloc (GH-156409)
(cherry picked from commit 6b1b90f) Co-authored-by: Kumar Aditya <kumaraditya@python.org>
1 parent 79b3919 commit 3f867d5

6 files changed

Lines changed: 303 additions & 139 deletions

File tree

Include/internal/pycore_pystate.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ struct PyInterpreterView {
354354
PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GuardCountdown(PyInterpreterState *interp);
355355
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterGuard_GetInterpreter(PyInterpreterGuard *guard);
356356

357+
extern int _PyInterpreterGuard_TryAcquire(PyInterpreterState *interp,
358+
PyInterpreterGuard *guard);
359+
extern void _PyInterpreterGuard_Release(PyInterpreterGuard *guard);
360+
357361
#ifdef __cplusplus
358362
}
359363
#endif

Include/internal/pycore_tracemalloc.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ struct
4444
__attribute__((packed))
4545
#endif
4646
tracemalloc_frame {
47-
/* filename cannot be NULL: "<unknown>" is used if the Python frame
48-
filename is NULL */
49-
PyObject *filename;
47+
/* Interned NUL terminated UTF-8 (surrogatepass) string.
48+
Cannot be NULL: "<unknown>" is used if the Python frame filename
49+
cannot be captured. */
50+
const char *filename;
5051
unsigned int lineno;
5152
};
5253

@@ -85,7 +86,7 @@ struct _tracemalloc_runtime_state {
8586
Protected by TABLES_LOCK(). */
8687
size_t peak_traced_memory;
8788
/* Hash table used as a set to intern filenames:
88-
PyObject* => PyObject*.
89+
char* (NUL terminated UTF-8 string) => NULL.
8990
Protected by the TABLES_LOCK(). */
9091
_Py_hashtable_t *filenames;
9192
/* Buffer to store a new traceback in traceback_new().

Lib/test/test_tracemalloc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,8 +1056,8 @@ def test_track(self):
10561056
self.check_track(False)
10571057

10581058
def test_track_without_gil(self):
1059-
# check that calling _PyTraceMalloc_Track() without holding the GIL
1060-
# works too
1059+
# check that calling PyTraceMalloc_Track() without the GIL
1060+
# (detached thread state) still captures the Python traceback
10611061
self.check_track(True)
10621062

10631063
def test_track_already_tracked(self):
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
:mod:`tracemalloc` no longer acquires the :term:`GIL` nor creates a
2+
temporary thread state to trace memory allocations: traceback frames now
3+
store plain UTF-8 strings instead of Python str objects, and tracebacks are
4+
captured using the Python thread state already associated with the calling
5+
thread, even if it is not attached. Threads without a Python thread state
6+
record the traceback as ``<unknown>``.

Python/pystate.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3388,8 +3388,8 @@ PyInterpreterGuard_FromCurrent(void)
33883388
return guard;
33893389
}
33903390

3391-
void
3392-
PyInterpreterGuard_Close(PyInterpreterGuard *guard)
3391+
static void
3392+
release_interp_guard(PyInterpreterGuard *guard)
33933393
{
33943394
PyInterpreterState *interp = guard->interp;
33953395
assert(interp != NULL);
@@ -3401,9 +3401,28 @@ PyInterpreterGuard_Close(PyInterpreterGuard *guard)
34013401
}
34023402

34033403
assert(old_value > 0);
3404+
}
3405+
3406+
void
3407+
PyInterpreterGuard_Close(PyInterpreterGuard *guard)
3408+
{
3409+
release_interp_guard(guard);
34043410
PyMem_RawFree(guard);
34053411
}
34063412

3413+
int
3414+
_PyInterpreterGuard_TryAcquire(PyInterpreterState *interp,
3415+
PyInterpreterGuard *guard)
3416+
{
3417+
return try_acquire_interp_guard(interp, guard);
3418+
}
3419+
3420+
void
3421+
_PyInterpreterGuard_Release(PyInterpreterGuard *guard)
3422+
{
3423+
release_interp_guard(guard);
3424+
}
3425+
34073426
PyInterpreterView *
34083427
PyInterpreterView_FromCurrent(void)
34093428
{

0 commit comments

Comments
 (0)