Skip to content

Commit 6a12aef

Browse files
committed
Remove unneeded 'mutex' member.
1 parent b1dd2f8 commit 6a12aef

4 files changed

Lines changed: 71 additions & 3 deletions

File tree

Include/internal/pycore_gc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ extern int _PyGC_VisitStackRef(union _PyStackRef *ref, visitproc visit, void *ar
341341
#ifdef Py_GIL_DISABLED
342342
extern void _PyGC_VisitObjectsWorldStopped(PyInterpreterState *interp,
343343
gcvisitobjects_t callback, void *arg);
344+
extern Py_ssize_t _PyGC_GetMimallocAllocatedBytes(PyInterpreterState *interp);
344345
#endif
345346

346347
#ifdef __cplusplus

Include/internal/pycore_interp_structs.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,6 @@ struct _gc_runtime_state {
268268
Adjusted after each collection based on the fraction of objects found to
269269
be trash. */
270270
int adaptive_threshold;
271-
272-
/* Mutex held for gc_should_collect_mem_usage(). */
273-
PyMutex mutex;
274271
#else
275272
PyGC_Head *generation0;
276273
#endif

Python/gc_free_threading.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,47 @@ gc_visit_heaps(PyInterpreterState *interp, mi_block_visit_fun *visitor,
463463
return err;
464464
}
465465

466+
// Visitor for _PyGC_GetMimallocAllocatedBytes(): called once per heap area
467+
// when visit_blocks=false. Sums area->used * area->block_size.
468+
static bool
469+
mimalloc_used_area_visitor(const mi_heap_t *heap, const mi_heap_area_t *area,
470+
void *block, size_t block_size, void *arg)
471+
{
472+
if (block == NULL) {
473+
*(Py_ssize_t *)arg += (Py_ssize_t)(area->used * area->block_size);
474+
}
475+
return true;
476+
}
477+
478+
// Return the total bytes in use across all mimalloc heaps for all threads in
479+
// the interpreter, plus the per-interp abandoned pool.
480+
Py_ssize_t
481+
_PyGC_GetMimallocAllocatedBytes(PyInterpreterState *interp)
482+
{
483+
Py_ssize_t total = 0;
484+
_PyEval_StopTheWorld(interp);
485+
HEAD_LOCK(&_PyRuntime);
486+
_Py_FOR_EACH_TSTATE_UNLOCKED(interp, p) {
487+
struct _mimalloc_thread_state *m =
488+
&((_PyThreadStateImpl *)p)->mimalloc;
489+
if (!_Py_atomic_load_int(&m->initialized)) {
490+
continue;
491+
}
492+
for (int h = 0; h < _Py_MIMALLOC_HEAP_COUNT; h++) {
493+
mi_heap_visit_blocks(&m->heaps[h], false,
494+
mimalloc_used_area_visitor, &total);
495+
}
496+
}
497+
mi_abandoned_pool_t *pool = &interp->mimalloc.abandoned_pool;
498+
for (uint8_t tag = 0; tag < _Py_MIMALLOC_HEAP_COUNT; tag++) {
499+
_mi_abandoned_pool_visit_blocks(pool, tag, false,
500+
mimalloc_used_area_visitor, &total);
501+
}
502+
HEAD_UNLOCK(&_PyRuntime);
503+
_PyEval_StartTheWorld(interp);
504+
return total;
505+
}
506+
466507
static inline void
467508
gc_visit_stackref(_PyStackRef stackref)
468509
{

Python/sysmodule.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Data members:
1919
#include "pycore_call.h" // _PyObject_CallNoArgs()
2020
#include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer()
2121
#include "pycore_frame.h" // _PyInterpreterFrame
22+
#include "pycore_gc.h" // _PyGC_GetMimallocAllocatedBytes()
2223
#include "pycore_import.h" // _PyImport_SetDLOpenFlags()
2324
#include "pycore_initconfig.h" // _PyStatus_EXCEPTION()
2425
#include "pycore_interpframe.h" // _PyFrame_GetFirstComplete()
@@ -2060,6 +2061,32 @@ sys_getallocatedblocks_impl(PyObject *module)
20602061
return _Py_GetGlobalAllocatedBlocks();
20612062
}
20622063

2064+
PyDoc_STRVAR(sys__get_mimalloc_allocated_bytes__doc__,
2065+
"_get_mimalloc_allocated_bytes($module, /)\n"
2066+
"--\n"
2067+
"\n"
2068+
"Return total bytes allocated across all mimalloc heaps in this interpreter.\n"
2069+
"\n"
2070+
"Free-threaded build only. Stops the world while reading per-thread heap\n"
2071+
"structures. Intended for benchmarking: the OS RSS does not reliably reflect\n"
2072+
"Python's live memory because mimalloc retains freed pages.\n"
2073+
"Raises NotImplementedError on the GIL-enabled build.");
2074+
2075+
static PyObject *
2076+
sys__get_mimalloc_allocated_bytes(PyObject *module, PyObject *Py_UNUSED(ignored))
2077+
{
2078+
#ifdef Py_GIL_DISABLED
2079+
PyInterpreterState *interp = _PyInterpreterState_GET();
2080+
Py_ssize_t total = _PyGC_GetMimallocAllocatedBytes(interp);
2081+
return PyLong_FromSsize_t(total);
2082+
#else
2083+
PyErr_SetString(PyExc_NotImplementedError,
2084+
"sys._get_mimalloc_allocated_bytes() is only available "
2085+
"on the free-threaded build");
2086+
return NULL;
2087+
#endif
2088+
}
2089+
20632090
/*[clinic input]
20642091
sys.getunicodeinternedsize -> Py_ssize_t
20652092
@@ -2927,6 +2954,8 @@ static PyMethodDef sys_methods[] = {
29272954
SYS_GETDEFAULTENCODING_METHODDEF
29282955
SYS_GETDLOPENFLAGS_METHODDEF
29292956
SYS_GETALLOCATEDBLOCKS_METHODDEF
2957+
{"_get_mimalloc_allocated_bytes", sys__get_mimalloc_allocated_bytes,
2958+
METH_NOARGS, sys__get_mimalloc_allocated_bytes__doc__},
29302959
SYS_GETUNICODEINTERNEDSIZE_METHODDEF
29312960
SYS_GETFILESYSTEMENCODING_METHODDEF
29322961
SYS_GETFILESYSTEMENCODEERRORS_METHODDEF

0 commit comments

Comments
 (0)