rust/library/std/src
Matthias Krüger f62aa415c3
Rollup merge of #124881 - Sp00ph:reentrant_lock_tid, r=joboet
Use ThreadId instead of TLS-address in `ReentrantLock`

Fixes #123458

`ReentrantLock` currently uses the address of a thread local variable as an ID that's unique across all currently running threads. This can lead to uninituitive behavior as in #123458 if TLS blocks get reused. This PR changes `ReentrantLock` to instead use the `ThreadId` provided by `std` as the unique ID. `ThreadId` guarantees uniqueness across the lifetime of the whole process, so we don't need to worry about reusing IDs of terminated threads. The main appeal of this PR is thus the possibility of changing the `ReentrantLock` API to guarantee that if a thread leaks a lock guard, no other thread may ever acquire that lock again.

This does entail some complications:
- previously, the only way to retrieve the current thread ID would've been using `thread::current().id()` which creates a temporary `Arc` and which isn't available in TLS destructors. As part of this PR, the thread ID instead gets cached in its own thread local, as suggested [here](https://github.com/rust-lang/rust/issues/123458#issuecomment-2038207704).
- `ThreadId` is always 64-bit whereas the current implementation uses a usize-sized ID. Since this ID needs to be updated atomically, we can't simply use a single atomic variable on 32 bit platforms. Instead, we fall back to using a (sound) seqlock on 32-bit platforms, which works because only one thread at a time can write to the ID. This seqlock is technically susceptible to the ABA problem, but the attack vector to create actual unsoundness has to be very specific:
  - You would need to be able to lock+unlock the lock exactly 2^31 times (or a multiple thereof) while a thread trying to lock it sleeps
  - The sleeping thread would have to suspend after reading one half of the thread id but before reading the other half
  - The teared result from combining the halves of the thread ID would have to exactly line up with the sleeping thread's ID

The risk of this occurring seems slim enough to be acceptable to me, but correct me if I'm wrong. This also means that the size of the lock increases by 8 bytes on 32-bit platforms, but this also shouldn't be an issue.

Performance wise, I did some crude testing of the only case where this could lead to real slowdowns, which is the case of locking a `ReentrantLock` that's already locked by the current thread. On both aarch64 and x86-64, there is (expectedly) pretty much no performance hit. I didn't have any 32-bit platforms to test the seqlock performance on, so I did the next best thing and just forced the 64-bit platforms to use the seqlock implementation. There, the performance degraded by ~1-2ns/(lock+unlock) on x86-64 and ~6-8ns/(lock+unlock) on aarch64, which is measurable but seems acceptable to me seeing as 32-bit platforms should be a small minority anyways.

cc `@joboet` `@RalfJung` `@CAD97`
2024-07-18 18:10:14 +02:00
..
backtrace remove redundant imports 2023-12-10 10:56:22 +08:00
collections std: Unsafe-wrap HashMap::get_many_unchecked_mut 2024-07-14 16:49:16 -07:00
env remove redundant imports 2023-12-10 10:56:22 +08:00
error core/any: remove Provider trait 2023-08-13 13:07:53 -06:00
f16 Add classify and related methods for f16 and f128 2024-07-14 18:44:43 -04:00
f32 Extract repeated constants from f32 and f64 source 2024-06-24 00:42:21 -05:00
f64 Extract repeated constants from f32 and f64 source 2024-06-24 00:42:21 -05:00
f128 Add classify and related methods for f16 and f128 2024-07-14 18:44:43 -04:00
ffi std: Unsafe-wrap OSStr{,ing}::from_encoded_bytes_unchecked 2024-07-14 16:59:12 -07:00
fs Auto merge of #125935 - madsmtm:merge-os-apple, r=workingjubilee 2024-07-14 16:28:07 +00:00
hash Add blank lines after module-level //! comments. 2024-06-20 09:23:20 +10:00
io std: Unsafe-wrap std::io 2024-07-14 17:17:55 -07:00
net Replace MaybeUninit::uninit_array() with array repeat expression. 2024-06-24 10:23:50 -07:00
num removed nonfunctioning benchmark 2024-01-11 11:30:12 -05:00
os Mention how you can go from BorrowedFd to OwnedFd and back 2024-07-17 14:34:00 +02:00
panic review: fix nits and move panic safety tests to the correct place 2020-09-25 23:10:24 +02:00
path Rollup merge of #127297 - the8472:path-new-hash, r=Nilstrieb 2024-07-07 14:22:00 +02:00
prelude Avoid comments that describe multiple use items. 2024-07-17 08:02:46 +10:00
process Remove DWORD 2024-07-15 05:01:22 +00:00
sync Rollup merge of #124881 - Sp00ph:reentrant_lock_tid, r=joboet 2024-07-18 18:10:14 +02:00
sys Rollup merge of #127845 - workingjubilee:actually-break-up-big-ass-stack-overflow-fn, r=joboet 2024-07-17 19:53:28 -05:00
sys_common std: Unsafe-wrap in Wtf8 impl 2024-07-14 17:44:13 -07:00
thread Rollup merge of #124881 - Sp00ph:reentrant_lock_tid, r=joboet 2024-07-18 18:10:14 +02:00
time Rollup merge of #103056 - beetrees:timespec-bug-fix, r=thomcc 2023-05-05 18:40:32 +05:30
alloc.rs Unify guarantees about the default allocator 2024-06-11 17:13:26 +02:00
ascii.rs Add the basic ascii::Char type 2023-05-03 22:09:33 -07:00
backtrace.rs std: move sys_common::backtrace to sys 2024-06-16 13:14:01 +02:00
env.rs Rollup merge of #125206 - mgeisler:simplify-std-env-vars, r=jhpratt,tgross35 2024-07-16 20:10:09 -05:00
error.rs std: move sys_common::backtrace to sys 2024-06-16 13:14:01 +02:00
f16.rs Add more f16 and f128 library functions and constants 2024-06-25 01:32:36 -04:00
f32.rs variable-precision float operations behave non-deterministically 2024-05-02 18:57:30 +02:00
f64.rs std: removes logarithms family function edge cases handling for solaris. 2024-07-14 23:20:46 +01:00
f128.rs Add more f16 and f128 library functions and constants 2024-06-25 01:32:36 -04:00
fs.rs Rollup merge of #126140 - eduardosm:stabilize-fs_try_exists, r=Amanieu 2024-06-22 19:33:55 +02:00
keyword_docs.rs Mention labelled blocks in break docs 2024-03-15 10:51:57 -07:00
lib.miri.rs add 'x.py miri', and make it work for 'library/{core,alloc,std}' 2024-04-03 20:27:20 +02:00
lib.rs Rollup merge of #126776 - nnethercote:rustfmt-use-pre-cleanups-2, r=cuviper 2024-07-16 20:10:10 -05:00
macros.rs Document the column numbers for the dbg! macro 2024-07-17 14:10:41 +02:00
num.rs Replace version placeholders for 1.79 2024-05-01 21:01:51 -04:00
panic.rs Use payload_as_str instead of two downcasts. 2024-06-12 13:15:29 +02:00
panicking.rs fix interleaved panic output 2024-07-12 11:52:04 -04:00
pat.rs Add pattern types to parser 2024-04-08 11:57:17 +00:00
path.rs Rollup merge of #127297 - the8472:path-new-hash, r=Nilstrieb 2024-07-07 14:22:00 +02:00
process.rs Fix minor typos in std::process doc on Win argv 2024-07-13 16:56:25 -07:00
rt.rs Rollup merge of #126776 - nnethercote:rustfmt-use-pre-cleanups-2, r=cuviper 2024-07-16 20:10:10 -05:00
time.rs Rust is a proper name: rust → Rust 2024-03-07 07:49:22 +01:00