X Tutup
The Wayback Machine - https://web.archive.org/web/20240120224934/https://github.com/python/cpython/issues/112529
Skip to content
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

Make the garbage collector thread-safe in --disable-gil builds #112529

Open
Tracked by #108219
colesbury opened this issue Nov 29, 2023 · 0 comments
Open
Tracked by #108219

Make the garbage collector thread-safe in --disable-gil builds #112529

colesbury opened this issue Nov 29, 2023 · 0 comments
Assignees
Labels
3.13 new features, bugs and security fixes topic-free-threading type-feature A feature request or enhancement

Comments

@colesbury
Copy link
Contributor

colesbury commented Nov 29, 2023

Feature or enhancement

Python's cyclic garbage collector relies on the global interpreter lock for thread-safety. There are a number of changes needed to make the GC thread-safe in --disable-gil builds.

My intention is to implement these as a series of smaller changes.

  • Garbage collection is guarded by gcstate->collecting. This need to be made thread-safe.
  • The --disable-gil builds should stop-the-world when finding garbage, but not when calling finalizers or destructors. (depends on Implement stop-the-world functionality (for --disable-gil builds) #111964)
  • The --disable-gil builds should find GC-enabled objects by traversing the mimalloc heaps, because the _gc_next/_gc_prev lists are not thread-safe. (Note it's safe to use the lists during stop-the-world pauses; we just can't maintain them safely during normal Python execution).
  • The --disable-gil builds should probably use only a single generation to avoid frequent stop-the-world pauses
  • Eventually, we can get rid of the GC pre-header in --disable-gil builds to save memory. (This will require updating the trashcan mechanism.)

See also #111964

Linked PRs

@colesbury colesbury added type-feature A feature request or enhancement 3.13 new features, bugs and security fixes topic-free-threading labels Nov 29, 2023
@colesbury colesbury self-assigned this Nov 29, 2023
colesbury added a commit to colesbury/cpython that referenced this issue Nov 29, 2023
The `collecting` field in `GCState` is used to prevent overlapping garbage
collections within the same interpreter. This is updated to use atomic
operations in order to be thread-safe in `--disable-gil` builds.

The GC code is refactored a bit to support this. More of the logic is pushed
down to `gc_collect_main()` so that we can safely order the logic setting
`collecting`, the selection of the generation, and the invocation of callbacks
with respect to the atomic operations and the (future) stop-the-world pauses.

The change uses atomic operations for both `--disable-gil` and the default
build (with the GIL) to avoid extra `#ifdef` guards and ease the maintenance
burden.
pablogsal pushed a commit that referenced this issue Dec 11, 2023
* gh-112529: Use atomic operations for `gcstate->collecting`

The `collecting` field in `GCState` is used to prevent overlapping garbage
collections within the same interpreter. This is updated to use atomic
operations in order to be thread-safe in `--disable-gil` builds.

The GC code is refactored a bit to support this. More of the logic is pushed
down to `gc_collect_main()` so that we can safely order the logic setting
`collecting`, the selection of the generation, and the invocation of callbacks
with respect to the atomic operations and the (future) stop-the-world pauses.

The change uses atomic operations for both `--disable-gil` and the default
build (with the GIL) to avoid extra `#ifdef` guards and ease the maintenance
burden.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 5, 2024
colesbury added a commit to colesbury/cpython that referenced this issue Jan 5, 2024
…ator

The GC implementation for free-threaded builds will need to accurately
detect if the debug allocator is used because it affects the offset of
the Python object from the beginning of the memory allocation. The
current implementation of `_PyMem_DebugEnabled` only considers if the
debug allocator is the outer-most allocator; it doesn't handle the case
of "hooks" like tracemalloc being used on top of the debug allocator.

This change enables more accurate detection of the debug allocator by
tracking when debug hooks are enabled.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 5, 2024
…ator

The GC implementation for free-threaded builds will need to accurately
detect if the debug allocator is used because it affects the offset of
the Python object from the beginning of the memory allocation. The
current implementation of `_PyMem_DebugEnabled` only considers if the
debug allocator is the outer-most allocator; it doesn't handle the case
of "hooks" like tracemalloc being used on top of the debug allocator.

This change enables more accurate detection of the debug allocator by
tracking when debug hooks are enabled.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 5, 2024
colesbury added a commit to colesbury/cpython that referenced this issue Jan 5, 2024
…ator

The GC implementation for free-threaded builds will need to accurately
detect if the debug allocator is used because it affects the offset of
the Python object from the beginning of the memory allocation. The
current implementation of `_PyMem_DebugEnabled` only considers if the
debug allocator is the outer-most allocator; it doesn't handle the case
of "hooks" like tracemalloc being used on top of the debug allocator.

This change enables more accurate detection of the debug allocator by
tracking when debug hooks are enabled.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 5, 2024
colesbury added a commit to colesbury/cpython that referenced this issue Jan 16, 2024
…ator

The GC implementation for free-threaded builds will need to accurately
detect if the debug allocator is used because it affects the offset of
the Python object from the beginning of the memory allocation. The
current implementation of `_PyMem_DebugEnabled` only considers if the
debug allocator is the outer-most allocator; it doesn't handle the case
of "hooks" like tracemalloc being used on top of the debug allocator.

This change enables more accurate detection of the debug allocator by
tracking when debug hooks are enabled.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 16, 2024
DinoV pushed a commit that referenced this issue Jan 16, 2024
…113747)

* gh-112529: Track if debug allocator is used as underlying allocator

The GC implementation for free-threaded builds will need to accurately
detect if the debug allocator is used because it affects the offset of
the Python object from the beginning of the memory allocation. The
current implementation of `_PyMem_DebugEnabled` only considers if the
debug allocator is the outer-most allocator; it doesn't handle the case
of "hooks" like tracemalloc being used on top of the debug allocator.

This change enables more accurate detection of the debug allocator by
tracking when debug hooks are enabled.

* Simplify _PyMem_DebugEnabled
colesbury added a commit to colesbury/cpython that referenced this issue Jan 16, 2024
The free-threaded build's garbage collector implementation will need to
find GC objects by traversing mimalloc heaps. This hooks up the
allocation calls with the correct heaps by using a thread-local
"current_obj_heap" variable.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 16, 2024
The free-threaded build's garbage collector implementation will need to
find GC objects by traversing mimalloc heaps. This hooks up the
allocation calls with the correct heaps by using a thread-local
"current_obj_heap" variable.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 18, 2024
…ator

The GC implementation for free-threaded builds will need to accurately
detect if the debug allocator is used because it affects the offset of
the Python object from the beginning of the memory allocation. The
current implementation of `_PyMem_DebugEnabled` only considers if the
debug allocator is the outer-most allocator; it doesn't handle the case
of "hooks" like tracemalloc being used on top of the debug allocator.

This change enables more accurate detection of the debug allocator by
tracking when debug hooks are enabled.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 18, 2024
colesbury added a commit to colesbury/cpython that referenced this issue Jan 18, 2024
The free-threaded build's garbage collector implementation will need to
find GC objects by traversing mimalloc heaps. This hooks up the
allocation calls with the correct heaps by using a thread-local
"current_obj_heap" variable.
colesbury added a commit to colesbury/cpython that referenced this issue Jan 18, 2024
colesbury added a commit to colesbury/cpython that referenced this issue Jan 18, 2024
colesbury added a commit to colesbury/cpython that referenced this issue Jan 18, 2024
corona10 pushed a commit that referenced this issue Jan 20, 2024
…h-114157)

* gh-112529: Use GC heaps for GC allocations in free-threaded builds

The free-threaded build's garbage collector implementation will need to
find GC objects by traversing mimalloc heaps. This hooks up the
allocation calls with the correct heaps by using a thread-local
"current_obj_heap" variable.

* Refactor out setting heap based on type
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 topic-free-threading type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

1 participant
X Tutup