New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mimalloc: additional integration and changes for --disable-gil
builds
#112532
Open
Tracked by
#108219
Labels
3.13
new features, bugs and security fixes
interpreter-core
(Objects, Python, Grammar, and Parser dirs)
topic-free-threading
type-feature
A feature request or enhancement
Comments
colesbury
added a commit
to colesbury/cpython
that referenced
this issue
Dec 8, 2023
In `--disable-gil` builds, the default allocator is now "mimalloc" and the "malloc" and "pymalloc" allocators are disabled.
corona10
pushed a commit
that referenced
this issue
Dec 12, 2023
colesbury
added a commit
to colesbury/cpython
that referenced
this issue
Dec 18, 2023
In `--disable-gil` builds, we now use four separate heaps in anticipation of using mimalloc to find GC objects when the GIL is disabled. To support this, we also make a few changes to mimalloc: * Heap and mi_tld_t initialization is split from allocation. This allows us to have a per-PyThreadState mi_tld_t, which is important to keep interpreter isolation, since the same OS thread may run in multiple interpreters (using different PyThreadStates.) * The pool of abandoned segments is refactored into its own struct. This allows us to use different pools for different interpreters so that we can preserve interpreter isolation. * Heap abandoning (mi_heap_collect_ex) can now be called from a different thread than the one that created the heap. This is necessary because we may clear and delete the containing PyThreadStates from a different thread during finalization and after fork().
colesbury
added a commit
to colesbury/cpython
that referenced
this issue
Dec 18, 2023
In `--disable-gil` builds, we now use four separate heaps in anticipation of using mimalloc to find GC objects when the GIL is disabled. To support this, we also make a few changes to mimalloc: * Heap and mi_tld_t initialization is split from allocation. This allows us to have a per-PyThreadState mi_tld_t, which is important to keep interpreter isolation, since the same OS thread may run in multiple interpreters (using different PyThreadStates.) * The pool of abandoned segments is refactored into its own struct. This allows us to use different pools for different interpreters so that we can preserve interpreter isolation. * Heap abandoning (mi_heap_collect_ex) can now be called from a different thread than the one that created the heap. This is necessary because we may clear and delete the containing PyThreadStates from a different thread during finalization and after fork().
colesbury
added a commit
to colesbury/cpython
that referenced
this issue
Dec 18, 2023
In `--disable-gil` builds, we now use four separate heaps in anticipation of using mimalloc to find GC objects when the GIL is disabled. To support this, we also make a few changes to mimalloc: * Heap and mi_tld_t initialization is split from allocation. This allows us to have a per-PyThreadState mi_tld_t, which is important to keep interpreter isolation, since the same OS thread may run in multiple interpreters (using different PyThreadStates.) * Heap abandoning (mi_heap_collect_ex) can now be called from a different thread than the one that created the heap. This is necessary because we may clear and delete the containing PyThreadStates from a different thread during finalization and after fork().
colesbury
added a commit
to colesbury/cpython
that referenced
this issue
Dec 18, 2023
In `--disable-gil` builds, we now use four separate heaps in anticipation of using mimalloc to find GC objects when the GIL is disabled. To support this, we also make a few changes to mimalloc: * `mi_heap_t` and `mi_tld_t` initialization is split from allocation. This allows us to have a `mi_tld_t` per-`PyThreadState`, which is important to keep interpreter isolation, since the same OS thread may run in multiple interpreters (using different PyThreadStates.) * Heap abandoning (mi_heap_collect_ex) can now be called from a different thread than the one that created the heap. This is necessary because we may clear and delete the containing PyThreadStates from a different thread during finalization and after fork().
colesbury
added a commit
to colesbury/cpython
that referenced
this issue
Dec 19, 2023
Mimalloc segments are data structures that contain memory allocations along with metadata. Each segment is "owned" by a thread. When a thread exits, it abandons its segments to a global pool to be later reclaimed by other threads. This changes the pool to be per-interpreter instead of process-wide. This will be important for when we use mimalloc to find GC objects in the `--disable-gil` builds. We want heaps to only store Python objects from a single interpreter. Absent this change, the abandoning and reclaiming process could break this isolation.
corona10
pushed a commit
that referenced
this issue
Dec 26, 2023
* gh-112532: Use separate mimalloc heaps for GC objects In `--disable-gil` builds, we now use four separate heaps in anticipation of using mimalloc to find GC objects when the GIL is disabled. To support this, we also make a few changes to mimalloc: * `mi_heap_t` and `mi_tld_t` initialization is split from allocation. This allows us to have a `mi_tld_t` per-`PyThreadState`, which is important to keep interpreter isolation, since the same OS thread may run in multiple interpreters (using different PyThreadStates.) * Heap abandoning (mi_heap_collect_ex) can now be called from a different thread than the one that created the heap. This is necessary because we may clear and delete the containing PyThreadStates from a different thread during finalization and after fork(). * Use enum instead of defines and guard mimalloc includes. * The enum typedef will be convenient for future PRs that use the type. * Guarding the mimalloc includes allows us to unconditionally include pycore_mimalloc.h from other header files that rely on things like `struct _mimalloc_thread_state`. * Only define _mimalloc_thread_state in Py_GIL_DISABLED builds
corona10
added a commit
to corona10/cpython
that referenced
this issue
Dec 26, 2023
corona10
added a commit
that referenced
this issue
Dec 26, 2023
colesbury
added a commit
to colesbury/cpython
that referenced
this issue
Jan 4, 2024
Mimalloc segments are data structures that contain memory allocations along with metadata. Each segment is "owned" by a thread. When a thread exits, it abandons its segments to a global pool to be later reclaimed by other threads. This changes the pool to be per-interpreter instead of process-wide. This will be important for when we use mimalloc to find GC objects in the `--disable-gil` builds. We want heaps to only store Python objects from a single interpreter. Absent this change, the abandoning and reclaiming process could break this isolation.
DinoV
pushed a commit
that referenced
this issue
Jan 4, 2024
* gh-112532: Isolate abandoned segments by interpreter Mimalloc segments are data structures that contain memory allocations along with metadata. Each segment is "owned" by a thread. When a thread exits, it abandons its segments to a global pool to be later reclaimed by other threads. This changes the pool to be per-interpreter instead of process-wide. This will be important for when we use mimalloc to find GC objects in the `--disable-gil` builds. We want heaps to only store Python objects from a single interpreter. Absent this change, the abandoning and reclaiming process could break this isolation. * Add missing '&_mi_abandoned_default' to 'tld_empty'
colesbury
added a commit
to colesbury/cpython
that referenced
this issue
Jan 5, 2024
Mimalloc pages are data structures that contain contiguous allocations of the same block size. Note that they are distinct from operating system pages. Mimalloc pages are contained in segments. When a thread exits, it abandons any segments and contained pages that have live allocations. These segments and pages may be later reclaimed by another thread. To support GC and certain thread-safety guarantees in free-threaded builds, we want pages to only be reclaimed by the corresponding heap in the claimant thread. For example, we want pages containing GC objects to only be claimed by GC heaps. This allows heaps and pages to be tagged with an integer tag that is used to ensure that abandoned pages are only claimed by heaps with the same tag. Heaps can be initialized with a tag (0-15); any page allocated by that heap copies the corresponding tag.
DinoV
pushed a commit
that referenced
this issue
Jan 5, 2024
* gh-112532: Tag mimalloc heaps and pages Mimalloc pages are data structures that contain contiguous allocations of the same block size. Note that they are distinct from operating system pages. Mimalloc pages are contained in segments. When a thread exits, it abandons any segments and contained pages that have live allocations. These segments and pages may be later reclaimed by another thread. To support GC and certain thread-safety guarantees in free-threaded builds, we want pages to only be reclaimed by the corresponding heap in the claimant thread. For example, we want pages containing GC objects to only be claimed by GC heaps. This allows heaps and pages to be tagged with an integer tag that is used to ensure that abandoned pages are only claimed by heaps with the same tag. Heaps can be initialized with a tag (0-15); any page allocated by that heap copies the corresponding tag. * Fix conversion warning
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
3.13
new features, bugs and security fixes
interpreter-core
(Objects, Python, Grammar, and Parser dirs)
topic-free-threading
type-feature
A feature request or enhancement
Feature or enhancement
Mimalloc was added as an allocator in #90815. The
--disable-gil
builds need further integration with mimalloc, as well as some modifications to mimalloc to support thread-safe garbage collection in--disable-gil
builds and the dictionary accesses that mostly avoid locking.These changes can be split up across multiple PRs.
PyMem_Malloc
calls, but we need separate heaps forPyObject_Malloc
andPyObject_GC_New
. We should associate somemi_heap_t
s with eachPyThreadState
. Every PyThreadState needs four heaps: one for PyMem_Malloc, one for non-GC objects (via PyObject_Malloc), one for GC objects with managed dicts (extra pre-header) and one for GC objects without a managed dict. We need some way to know which heap to use in_PyObject_MiMalloc
. There's not a great way to do this, but I suggest adding something like a "current pyobject heap" variable to PyThreadState. It should generally point to thePyObject_Malloc
heap, butPyObject_GC_New
should temporarily override it to point to the correct GC heap when called--disable-gil
should imply--with-mimalloc
and require mimalloc (i.e., disallow changing the allocator withPYTHONMALLOC
).cc @DinoV
Linked PRs
--disable-gil
builds #112883The text was updated successfully, but these errors were encountered: