aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/lock.c
Commit message (Collapse)AuthorAge
* gh-111178: Fix function signatures to fix undefined behavior (#131191)Victor Stinner2025-03-14
|
* gh-131082: Add missing guards for WIN32_LEAN_AND_MEAN (#131044)Max Bachmann2025-03-11
| | | | | * Add missing guards for WIN32_LEAN_AND_MEAN * add missing whitespaces
* gh-125139: use `_PyRecursiveMutex` in `_thread.RLock` (#125144)Kumar Aditya2024-10-14
|
* gh-121368: Fix seq lock memory ordering in _PyType_Lookup (#121388)Sam Gross2024-07-08
| | | | | | | | | The `_PySeqLock_EndRead` function needs an acquire fence to ensure that the load of the sequence happens after any loads within the read side critical section. The missing fence can trigger bugs on macOS arm64. Additionally, we need a release fence in `_PySeqLock_LockWrite` to ensure that the sequence update is visible before any modifications to the cache entry.
* gh-117511: Make PyMutex public in the non-limited API (#117731)Sam Gross2024-06-20
|
* gh-117657: Fix TSAN race involving import lock (#118523)Sam Gross2024-06-06
| | | | | This adds a `_PyRecursiveMutex` type based on `PyMutex` and uses that for the import lock. This fixes some data races in the free-threaded build and generally simplifies the import lock code.
* gh-110850: Remove _PyTime_TimeUnchecked() function (#118552)Victor Stinner2024-05-05
| | | | | | | | | | | | | Use the new public Raw functions: * _PyTime_PerfCounterUnchecked() with PyTime_PerfCounterRaw() * _PyTime_TimeUnchecked() with PyTime_TimeRaw() * _PyTime_MonotonicUnchecked() with PyTime_MonotonicRaw() Remove internal functions: * _PyTime_PerfCounterUnchecked() * _PyTime_TimeUnchecked() * _PyTime_MonotonicUnchecked()
* gh-118332: Fix deadlock involving stop the world (#118412)Sam Gross2024-04-30
| | | | | | Avoid detaching thread state when stopping the world. When re-attaching the thread state, the thread would attempt to resume the top-most critical section, which might now be held by a thread paused for our stop-the-world request.
* gh-117657: Quiet erroneous TSAN reports of data races in `_PySeqLock` (#117955)mpage2024-04-17
| | | | | | | | Quiet erroneous TSAN reports of data races in `_PySeqLock` TSAN reports a couple of data races between the compare/exchange in `_PySeqLock_LockWrite` and the non-atomic loads in `_PySeqLock_{Abandon,Unlock}Write`. This is another instance of TSAN incorrectly modeling failed compare/exchange as a write instead of a load.
* gh-114271: Fix race in `Thread.join()` (#114839)mpage2024-03-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There is a race between when `Thread._tstate_lock` is released[^1] in `Thread._wait_for_tstate_lock()` and when `Thread._stop()` asserts[^2] that it is unlocked. Consider the following execution involving threads A, B, and C: 1. A starts. 2. B joins A, blocking on its `_tstate_lock`. 3. C joins A, blocking on its `_tstate_lock`. 4. A finishes and releases its `_tstate_lock`. 5. B acquires A's `_tstate_lock` in `_wait_for_tstate_lock()`, releases it, but is swapped out before calling `_stop()`. 6. C is scheduled, acquires A's `_tstate_lock` in `_wait_for_tstate_lock()` but is swapped out before releasing it. 7. B is scheduled, calls `_stop()`, which asserts that A's `_tstate_lock` is not held. However, C holds it, so the assertion fails. The race can be reproduced[^3] by inserting sleeps at the appropriate points in the threading code. To do so, run the `repro_join_race.py` from the linked repo. There are two main parts to this PR: 1. `_tstate_lock` is replaced with an event that is attached to `PyThreadState`. The event is set by the runtime prior to the thread being cleared (in the same place that `_tstate_lock` was released). `Thread.join()` blocks waiting for the event to be set. 2. `_PyInterpreterState_WaitForThreads()` provides the ability to wait for all non-daemon threads to exit. To do so, an `is_daemon` predicate was added to `PyThreadState`. This field is set each time a thread is created. `threading._shutdown()` now calls into `_PyInterpreterState_WaitForThreads()` instead of waiting on `_tstate_lock`s. [^1]: https://github.com/python/cpython/blob/441affc9e7f419ef0b68f734505fa2f79fe653c7/Lib/threading.py#L1201 [^2]: https://github.com/python/cpython/blob/441affc9e7f419ef0b68f734505fa2f79fe653c7/Lib/threading.py#L1115 [^3]: https://github.com/mpage/cpython/commit/81946532792f938cd6f6ab4c4ff92a4edf61314f --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Antoine Pitrou <antoine@python.org>
* gh-114271: Make `_thread.ThreadHandle` thread-safe in free-threaded builds ↵mpage2024-03-01
| | | | | | | | | | | | | | | | | (GH-115190) Make `_thread.ThreadHandle` thread-safe in free-threaded builds We protect the mutable state of `ThreadHandle` using a `_PyOnceFlag`. Concurrent operations (i.e. `join` or `detach`) on `ThreadHandle` block until it is their turn to execute or an earlier operation succeeds. Once an operation has been applied successfully all future operations complete immediately. The `join()` method is now idempotent. It may be called multiple times but the underlying OS thread will only be joined once. After `join()` succeeds, any future calls to `join()` will succeed immediately. The internal thread handle `detach()` method has been removed.
* gh-110850: Rename internal PyTime C API functions (#115734)Victor Stinner2024-02-20
| | | | | | | | | | | | | | | | | Rename functions: * _PyTime_GetSystemClock() => _PyTime_TimeUnchecked() * _PyTime_GetPerfCounter() => _PyTime_PerfCounterUnchecked() * _PyTime_GetMonotonicClock() => _PyTime_MonotonicUnchecked() * _PyTime_GetSystemClockWithInfo() => _PyTime_TimeWithInfo() * _PyTime_GetMonotonicClockWithInfo() => _PyTime_MonotonicWithInfo() * _PyTime_GetMonotonicClockWithInfo() => _PyTime_MonotonicWithInfo() Changes: * Remove "typedef PyTime_t PyTime_t;" which was "typedef PyTime_t _PyTime_t;" before a previous rename. * Update comments of "Unchecked" functions. * Remove invalid PyTime_Time() comment.
* gh-110850: Cleanup pycore_time.h includes (#115724)Victor Stinner2024-02-20
| | | | | <pycore_time.h> include is no longer needed to get the PyTime_t type in internal header files. This type is now provided by <Python.h> include. Add <pycore_time.h> includes to C files instead.
* gh-110850: Replace _PyTime_t with PyTime_t (#115719)Victor Stinner2024-02-20
| | | | | Run command: sed -i -e 's!\<_PyTime_t\>!PyTime_t!g' $(find -name "*.c" -o -name "*.h")
* gh-113743: Make the MRO cache thread-safe in free-threaded builds (#113930)Dino Viehland2024-02-15
| | | | | | | Makes _PyType_Lookup thread safe, including: Thread safety of the underlying cache. Make mutation of mro and type members thread safe Also _PyType_GetMRO and _PyType_GetBases are currently returning borrowed references which aren't safe.
* gh-111964: Add _PyRWMutex a "readers-writer" lock (gh-112859)Sam Gross2023-12-15
| | | | This adds `_PyRWMutex`, a "readers-writer" lock, which wil be used to serialize global stop-the-world pauses with per-interpreter pauses.
* gh-111863: Rename `Py_NOGIL` to `Py_GIL_DISABLED` (#111864)Hugo van Kemenade2023-11-20
| | | Rename Py_NOGIL to Py_GIL_DISABLED
* gh-111956: Add thread-safe one-time initialization. (gh-111960)Sam Gross2023-11-16
|
* gh-108724: Add PyMutex and _PyParkingLot APIs (gh-109344)Sam Gross2023-09-19
PyMutex is a one byte lock with fast, inlineable lock and unlock functions for the common uncontended case. The design is based on WebKit's WTF::Lock. PyMutex is built using the _PyParkingLot APIs, which provides a cross-platform futex-like API (based on WebKit's WTF::ParkingLot). This internal API will be used for building other synchronization primitives used to implement PEP 703, such as one-time initialization and events. This also includes tests and a mini benchmark in Tools/lockbench/lockbench.py to compare with the existing PyThread_type_lock. Uncontended acquisition + release: * Linux (x86-64): PyMutex: 11 ns, PyThread_type_lock: 44 ns * macOS (arm64): PyMutex: 13 ns, PyThread_type_lock: 18 ns * Windows (x86-64): PyMutex: 13 ns, PyThread_type_lock: 38 ns PR Overview: The primary purpose of this PR is to implement PyMutex, but there are a number of support pieces (described below). * PyMutex: A 1-byte lock that doesn't require memory allocation to initialize and is generally faster than the existing PyThread_type_lock. The API is internal only for now. * _PyParking_Lot: A futex-like API based on the API of the same name in WebKit. Used to implement PyMutex. * _PyRawMutex: A word sized lock used to implement _PyParking_Lot. * PyEvent: A one time event. This was used a bunch in the "nogil" fork and is useful for testing the PyMutex implementation, so I've included it as part of the PR. * pycore_llist.h: Defines common operations on doubly-linked list. Not strictly necessary (could do the list operations manually), but they come up frequently in the "nogil" fork. ( Similar to https://man.freebsd.org/cgi/man.cgi?queue) --------- Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>