GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Mimalloc differences from upstream · Issue #113141 · python/cpython

Mimalloc differences from upstream #113141

New issue
Copy link
New issue
Copy link
Open
Open
Mimalloc differences from upstream#113141
Copy link
Labels
3.13only security fixesonly security fixestopic-free-threading

Description

@colesbury
colesbury
opened on Dec 14, 2023
Issue body actions

This issue tracks divergence in our copy of mimalloc from upstream https://github.com/microsoft/mimalloc. The purpose is to help with upstreaming fixes and also so that our modifications are not lost as we pull in new mimalloc versions.

base version: v2.1.2

Simple bug fixes

  • gh-90815: Fix mimalloc build on WASI #111524 (fixed upstream)
  • gh-111544: Fix mimalloc build on AIX #111593
  • gh-111906: Remove unused function warnings during mimalloc build on FREEBSD #111907
  • gh-90815: Fix mimalloc atomic.h on Windows arm64 #111527
  • gh-112027: Don't print mimalloc warning after mmap() call #113372
  • gh-117547: Fix mimalloc compile error on OpenBSD #117548
  • gh-117755: Fix mimalloc for huge allocation on s390x #117809
  • gh-116984: Make mimalloc header includes relative to the current file #118808
  • gh-123022: Fix crash with Py_Initialize in background thread #123052 (May be specific to CPython's usage)
  • gh-123826: Fix Unused Static Warnings in Objects/mimalloc/prim/unix/prim.c #123827 (fixed upstream)
  • gh-158529: Prevent mimalloc calling system calls directly on Android #158530 (upstream commit microsoft/mimalloc@aef8faa, v3.6.0)

Mimalloc changes to support GC

  • gh-112532: Use separate mimalloc heaps for GC objects #113263
  • gh-112532: Isolate abandoned segments by interpreter #113717
  • gh-112532: Tag mimalloc heaps and pages #113742
  • gh-112532: Improve mimalloc page visiting #114133
  • gh-112529: Use _PyThread_Id() in mimalloc (free-threaded build) #115488

Mimalloc changes for lock-free reads (using QSBR)

  • gh-115103: Delay reuse of mimalloc pages that store PyObjects #115435

UWP (Universal Windows Platform) Support

  • gh-152433: Windows: allow build mimalloc for UWP #152477

Linked PRs

  • gh-113141: Upgrade mimalloc to upstream v3 #159718
  • gh-113141: Tune MI_SEGMENT_SLICE_SHIFT to 14 for using 16 Kib pages #160360
Reacted by Erlend E. Aasland, Kirill Podoprigora, Furkan Onder, Itamar Oren, Sam James, Julien Jerphanion, Grechko Sergii and EDM115

Activity

Next
  1. colesbury
    added
    3.13only security fixesonly security fixes
    topic-free-threading
    on Dec 14, 2023
  2. corona10 commented on Dec 18, 2023

    @corona10
    corona10
    on Dec 18, 2023
    Member
    More actions

    Hmm, how about generating patchfiles and storing them somewhere in the repository for records? :)
    I also need feedback about the solution from @vstinner since people in Red Hat is the best expert for this area.

    Reacted by Sam James
  3. corona10 commented on Dec 18, 2023

    @corona10
    corona10
    on Dec 18, 2023
    Member
    More actions

    And which commit is our mimalloc baseline code?
    I can spend time for implementing a tool that generating diff files and comparing them on the CI level if it looks okay :)

    Reacted by Sam James
  4. corona10 commented on Dec 18, 2023

    @corona10
    corona10
    on Dec 18, 2023
    Member
    More actions

    cc @DinoV

  5. vstinner commented on Dec 18, 2023

    @vstinner
    vstinner
    on Dec 18, 2023
    Member
    More actions

    Hmm, how about generating patchfiles and storing them somewhere in the repository for records? :)

    That sounds painful to maintain. I would prefer to have a process to upstream changes first (mimalloc), and then apply them downstream (Python).

    Here we wanted to move quickly to add mimalloc and fix all portability issues. But we should be more "upstream first" for following changes.

    Reacted by Sam James
  6. corona10 commented on Dec 18, 2023

    @corona10
    corona10
    on Dec 18, 2023
    Member
    More actions

    Ah okay if they accept our changes, it looks reasonable.

  7. colesbury commented on Dec 18, 2023

    @colesbury
    colesbury
    on Dec 18, 2023
    ContributorAuthor
    More actions

    I created this issue in anticipation of further mimalloc changes. There will be changes to support GC in the --disable-gil builds and a few for the optimistic dict accesses. We are going to need to continue to move quickly. An upstream first model is not going to work yet.

    I don't think it will be too hard to pull in new mimalloc versions. I've done it a few times in the nogil forks: diff vs. base to get patch file, patch new version, fix merge conflicts. We can write up the workflow, but I think automation is overkill at this point.

    I had a nice chat with Daan (mimalloc author) on Friday and we got a chance to discuss some (but not all) of the mimalloc changes to support GC. I think we'll be able to get changes merged upstream, but for non-trivial changes I think it's helpful to understand and be able to explain how APIs are used in CPython. Even if time were not an issue, I would not want to be in a situation where we propose something upstream and then it turns out we needed something slightly different.

    Reacted by Donghee Na, Carl Meyer, Itamar Oren, Erlend E. Aasland and Eric Snow
  8. ericsnowcurrently commented on Jan 4, 2024

    @ericsnowcurrently
    ericsnowcurrently
    on Jan 4, 2024
    Member
    More actions

    CC @daanx

    Reacted by Erlend E. Aasland
  9. hroncok
    added a commit that references this issue on Apr 12, 2024

    Link *Mimalloc differences from upstream* python#113141

    8aa3206
  10. daanx
    added a commit that references this issue on May 18, 2024

    make mimalloc includes relative to the current file, upstream of pyth…

    381da05
  11. daanx commented on May 19, 2024

    @daanx
    daanx
    on May 19, 2024
    More actions

    I have started upstreaming mimalloc specific modifications into mimalloc to make it easier to downstream future releases of mimalloc. The ideal goal would be to enable Python to pull in mimalloc with no further modifications -- let's see how far we can get.

    For now, I am documenting here which commits fix particular issues together with the version of mimalloc that will have these commits. (last update: 2024-06-03)

    Planned for v2.1.8

    Mimalloc changes to support GC

    • gh-112532: Isolate abandoned segments by interpreter #113717 (v2.1.8, various upstream commits, some are: microsoft/mimalloc@d9aa19a (sub-processes), microsoft/mimalloc@8f87455 (visit arena abandoned per sub process), microsoft/mimalloc@855e3b2 (all abandoned block visiting), and a concurrency "leak" fix microsoft/mimalloc@96b69d7)
      This now works with the new bitmap based abandoned segments which scales better.

    • gh-112532: Improve mimalloc page visiting #114133 (v2.1.8, upstream commit microsoft/mimalloc@f7fe5bf)
      (note: would like to check correctness of fast_divide and the range possible of bsize)

    Mimalloc changes for lock-free reads (using QSBR)

    • gh-115103: Delay reuse of mimalloc pages that store PyObjects #115435 TODO

    upstreamed in v2.1.7:

    Simple bug fixes

    • gh-90815: Fix mimalloc build on WASI #111524 (upstream commit microsoft/mimalloc@e1f6516, v2.1.6)
    • gh-111544: Fix mimalloc build on AIX #111593 (upstream commit microsoft/mimalloc@87c4012, v2.1.7)
    • gh-111906: Remove unused function warnings during mimalloc build on FREEBSD #111907 (upstream commit microsoft/mimalloc@87c4012, v2.1.7)
    • gh-90815: Fix mimalloc atomic.h on Windows arm64 #111527 (upstream commit microsoft/mimalloc@c48a212, v2.1.7)
    • gh-112027: Don't print mimalloc warning after mmap() call #113372 (upstream commit microsoft/mimalloc@92a8268, v2.1.7)
    • gh-117547: Fix mimalloc compile error on OpenBSD #117548 (upstream commit microsoft/mimalloc@87c4012, v2.1.7)
    • gh-117755: Fix mimalloc for huge allocation on s390x #117809 (upstream commit microsoft/mimalloc@78418b3, v2.1.7, issue Issue #876: Fix integer overflow on slice_count microsoft/mimalloc#877)
    • gh-116984: Make mimalloc header includes relative to the current file #118808 (upstream commit microsoft/mimalloc@381da05, v2.1.7)

    Mimalloc changes to support GC

    • gh-112532: Use separate mimalloc heaps for GC objects #113263 (upstream commit microsoft/mimalloc@710d613, v2.1.7) note: renamed _mi_heap_init_ex to _mi_heap_init (and the original heap init to mi_thread_heap_init).

    • gh-112532: Tag mimalloc heaps and pages #113742 (upstream commit microsoft/mimalloc@0c4041f, v2.1.7) note: added an error condition if page with a certain custom tag cannot be reclaimed in a heap with the same tag; is EINVAL strong enough? maybe make it EFAULT to abort in such case?. It should not happen though if used properly.
      (edit: I made it EFAULT to catch any bugs early)

    • [Make the garbage collector thread-safe in --disable-gil builds #112529: Use _PyThread_Id() in mimalloc (free-threaded build) gh-112529: Use _PyThread_Id() in mimalloc (free-threaded build) #115488](gh-112529: Use _PyThread_Id() in mimalloc (free-threaded build) #115488, v2.1.7) (upstream commit microsoft/mimalloc@66052f1)

    Reacted by Eli Schwartz, Sam James, Erlend E. Aasland, GalaxySnail, Sam Gross, Eric Snow, Itamar Oren, IceCodeNew, Yupei Liu, eihqnh and 4 more
  12. cdce8p commented on Jul 8, 2024

    @cdce8p
    cdce8p
    on Jul 8, 2024
    Contributor
    More actions

    For reference, just opened #121487 to address a deprecation warning with ATOMIC_VAR_INIT which was already fixed upstream in v1.8.4.

    Reacted by Sam Gross
  13. kwvg
    added a commit that references this issue on Oct 27, 2025

    Squashed 'depends/mimalloc/' changes from 91ba1f374..7a2a41134

    3e1d2ea
  14. kwvg
    added a commit that references this issue on Nov 7, 2025

    Squashed 'depends/mimalloc/' changes from 91ba1f374..b0958d81f

    cf419f0
  15. 4 remaining items

  16. vstinner
    added a commit that references this issue on May 13, 2026

    gh-148461: Use arc4random_buf() in mimalloc on Cygwin (#148462)

    fdf064c
  17. StanFromIreland commented on Jun 25, 2026

    @StanFromIreland
    StanFromIreland
    on Jun 25, 2026
    Member
    More actions

    We have four CodeQL warnings for bundled mimalloc:

    • https://github.com/python/cpython/security/code-scanning/84
    • https://github.com/python/cpython/security/code-scanning/85
    • https://github.com/python/cpython/security/code-scanning/87
    • https://github.com/python/cpython/security/code-scanning/86

    I wrote a PR upstream (microsoft/mimalloc#1321) to fix two and note the other two.

  18. daanx
    added 2 commits that reference this issue on Oct 8, 2026

    prevent syscalls on Android, upstream of python/cpython#158530 (and p…

    aef8faa

    UWP compilation, upstream of python/cpython#152477 (and python/cpytho…

    7e767bd
  19. corona10 commented on Oct 15, 2026

    @corona10
    corona10
    on Oct 15, 2026
    Member
    More actions

    Just for record: #159111 is about upgrading mimalloc from 2.1.2 to 2.5.2

  20. daanx commented on Oct 17, 2026

    @daanx
    daanx
    on Oct 17, 2026
    More actions

    Just an update: recently started working on integrating mimalloc v3 in CPython (sorry, I hope this does not interfere with your work @corona10 -- I wasn't aware this effort was started).

    I am hoping mimalloc v3 can become a "drop-in" without needing any patches from the CPython side -- so we can easily upgrade mimalloc in the future if there are security fixes or new features (like the recent profiler hooks) etc.

    The main item that I added is a good interface for the quiescent-state-based-reclamation (QSBR), and I think I found a good
    abstraction for this where all lifetime management is now done on the mimalloc side (and part of the regular release).
    Hope this design can work as the interface is now more general and abstract (so maybe it can work for other runtimes as well).

    With the new first-class heaps in mimalloc v3, we can make heaps that are QSBR enabled and for those the pages are
    tracked so we never free the memory if there might still be outstanding readers. The CPython side only needs to define
    helpers for the actual QSBR goals etc. This is quite minimal now (https://github.com/microsoft/mimalloc/blob/dev3/include/mimalloc/qsbr.h):

    typedef struct mi_page_qsbr_s mi_page_qsbr_t;
    typedef struct mi_heap_qsbr_s mi_heap_qsbr_t;
    void mi_heap_qsbr_init(mi_heap_qsbr_t* heap);
    void mi_page_qsbr_clear(mi_page_qsbr_t* page);
    bool mi_page_qsbr_is_clear(const mi_page_qsbr_t* page);
    bool mi_page_qsbr_should_delay(mi_page_qsbr_t* page, mi_heap_qsbr_t* heap, size_t page_bytes);

    I implemented all this on the mimalloc side where this gets enabled by defining MI_QSBR=1.
    Now, I don't know CPython very well, so I used an agent to interface CPython with the new v3 API and
    created a fork here: https://github.com/daanx/cpython/tree/mimalloc-v3 (this is temporary and more
    a proof of concept and to help others/Sam to integrate this; I can make it into a PR if that is better?)

    The actual changes to CPython are in commit e253ecc2, while the other commits are just including the new vendored mimalloc v3 sources.

    It all seems to work already :-) -- but again, I am not an expert here so someone needs
    to review the changes and see if it indeed is all ok; @colesbury: hope you can take a look?

    Here are some other more minor parts that were addressed as summarized by an agent:

    CPython-side changes in my fork

    The following are in commit e253ecc2 in the cpython fork.

    • Heaps per interpreter instead of tags. Create 4 mi_heap_t*  per interpreter (mem, object, gc, gc_pre). Each thread state gets its per-thread heaps once with mi_heap_theap()  and allocates through  mi_theap_* . Pages never leave their heap and reclaim only happens within a heap. So tag, the per-interpreter abandoned pools and  _mi_heap_init_ex / _mi_tld_init  all go away. Subprocs aren't needed, and wouldn't fit: one OS thread can run thread states from several interpreters, but can only belong to one subproc.

    • Simpler GC walk. It becomes  mi_heap_visit_blocks(gc_heap, ...)  per interpreter, covering all threads and abandoned pages. No loop over thread states, no lock, no separate abandoned visit.

    • Smaller installed headers.  pycore_mimalloc.h then only needs opaque pointers, so only mimalloc.h has to be installed.

    • Cache the per-thread theaps in the thread state.  mi_heap_malloc has a single cache slot, so switching between 4 heaps would keep hitting the slow lookup. Get a mi_theap_t with mi_heap_theap(heap) in each thread state and use mi_theap_malloc.
      (or mi_theap_malloc_csize if the size is statically known).

    • Already upstream in v3: the MI_PRIM_THREAD_ID macro, the configurable debug fill bytes, MI_TSAN, the UWP fix and the Fix format specifiers for long err in numa bind warning message microsoft/mimalloc#1321 CodeQL fixes. The Crash in Py_Initialize in non-main thread in free-threading build #123022 patch no longer applies.

    Mimalloc v3 changes

    These are already committed in the latest dev3 in mimalloc.

    • Per-heap debug-fill offset. v3 fills whole blocks on alloc and free. Py_DEBUG free-threaded builds need the object header
      bytes left intact. Fixed in commit fc238b62.

    • Public "page owner thread id" call. gc_restore_tid needs it. Abandoned pages in v3 report 0 or 4, so it should return 0 for both. CPython would replace the segment lookup with: op->ob_tid = mi_thread_id_of(op);.
      Added size_t mi_thread_id_of(const void* p) in commit 9dac1fec.

    • Explicit "abandon this thread's per-heap state" call. The internal version, _mi_theap_delete, is commented out. CPython needs one on the owning thread (thread state cleared while the OS thread lives on), and one usable from another thread when the owner is dead (PyThreadState_Clear of other threads, fork child).
      Add mi_theap_delete and mi_theap_quiescent_abandon (commit 318f6817). Not sure in-how-far this is still needed
      with first-class heaps and heap-destroy/delete. Hope we can avoid calling this.

    • Fork safety. v2 was nearly lock-free. v3 uses some pthread mutexes and has no fork handlers, so a fork can deadlock the child. In the child, dead threads' pages also stay "owned", and a new thread can reuse the same thread id. Suggest mi_fork_prepare/parent/child()  or  pthread_atfork. Fixed in commit 1b7e73f3, 7ea8bfc0, and c084f15a.

    • Heap-walk bug (reproduced). Live blocks in OS-allocated pages that a live thread still owns are not visited. With  mi_option_disallow_arena_alloc, only 1 of 2 blocks was visited. The CPython GC would miss objects whenever mimalloc falls back to OS pages. Also, area->used over-counts blocks freed by other threads but not yet collected (fixed in 85f49529ca). fixed in commit b85f2d06, a9d447d3, f9262ecb.

    • Nice to have:

      • Public size-class thresholds or stats for _debugmallocstats. (not sure what to do?)
      • Fix the one -Wstatic-in-inline  warning (mi_forall_arenas). Otherwise static.c compiles cleanly with CPython-like flags. Fixed in commit cee18e1c.

    Running

    This is how I tested CPython on macOS from my fork:

    git clone --depth 1 --single-branch --branch mimalloc-v3 \
      https://github.com/daanx/cpython.git cpython-mimalloc-v3
    
    cd cpython-mimalloc-v3
    mkdir -p build/nogil
    cd build/nogil
    
    ../../configure --disable-gil
    make -j8
    ./python.exe -VV

    The version output should contain free-threading build. (On Linux, use ./python instead of ./python.exe

    Simple no-GIL test

    Run this from the same build directory. It checks that the GIL is actually disabled and runs four CPU-bound workers—not merely sleeping threads.

    ./python.exe -I - <<'PY'
    import sys
    import sysconfig
    import threading
    from concurrent.futures import ThreadPoolExecutor
    
    assert sysconfig.get_config_var("Py_GIL_DISABLED") == 1, "Not a free-threaded build"
    assert not sys._is_gil_enabled(), "GIL is enabled"
    
    n = 1_000_000
    barrier = threading.Barrier(4)
    
    def work(_):
        barrier.wait(timeout=30)
        return sum(i * i for i in range(n))
    
    with ThreadPoolExecutor(max_workers=4) as pool:
        results = list(pool.map(work, range(4)))
    
    expected = n * (n - 1) * (2 * n - 1) // 6
    assert results == [expected] * 4
    assert not sys._is_gil_enabled()
    print("GIL enabled:", sys._is_gil_enabled())
    print("PASS: four CPU-bound worker threads completed correctly")
    PY

    Repeat the regression tests:

    ./python.exe -m test -j4 --timeout 180 \
      test_gc test_threading test_capi.test_mem test_free_threading
    Reacted by Donghee Na
  21. corona10 commented on Oct 17, 2026

    @corona10
    corona10
    on Oct 17, 2026
    Member
    More actions

    @daanx I think that if we can move on to v3 directly, it would be better solution. I think that we need to run freethreading benchmark via Meta infrastructure by @mpage. Matt could help you.

  22. corona10 commented on Oct 17, 2026

    @corona10
    corona10
    on Oct 17, 2026
    Member
    More actions

    Could you send a draft PR for this?

  23. daanx commented on Oct 17, 2026

    @daanx
    daanx
    on Oct 17, 2026
    More actions

    26. @daanx I think that if we can move on to v3 directly, it would be better solution. I think that we need to run freethreading benchmark via Meta infrastructure by @mpage. Matt could help you

    Thank you @corona10 -- hope this didn't cause too much work. Yes, my current fork seems to work but I am not a CPython/NoGIL expert so better testing is needed and an expert needs to look at the CPython side changes at least. The mimalloc side changes are also well contained in one or two commits so that should help.

  24. daanx commented on Oct 17, 2026

    @daanx
    daanx
    on Oct 17, 2026
    More actions

    27. Could you send a draft PR for this?

    Yes.. but maybe it is better if some people first look at the current fork? It would perhaps be better if someone from CPython would create such PR -- I am not sure if I vendored mimalloc correctly etc.

  25. kevinprimeraquecreo-stack
    added this to Project_VKon Oct 18, 2026
  26. github-project-automation
    moved this to Todo in Project_VKon Oct 18, 2026
  27. kevinprimeraquecreo-stack
    added this to Project_VKon Oct 18, 2026
  28. corona10
    added a commit that references this issue on Oct 22, 2026

    pythongh-113141: Tune MI_SEGMENT_SLICE_SHIFT to 14 for using 16 Kib p…

    2e2a547
  29. corona10
    added a commit that references this issue on Nov 2, 2026

    gh-113141: Tune MI_SEGMENT_SLICE_SHIFT to 14 for using 16 Kib pages (g…

    4e0677a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixesonly security fixestopic-free-threading

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.