about summary refs log tree commit diff
path: root/library/std/src/thread
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-02-12 09:45:22 +0000
committerbors <bors@rust-lang.org>2024-02-12 09:45:22 +0000
commitb17491c8f6d555386104dfd82004c01bfef09c95 (patch)
treea5989f2b07f7c327915b98df107fe99cc282852d /library/std/src/thread
parentaebf4511e919e8df6db8a9217fd56316a9f8a38f (diff)
parent04282db5b3a980c95e16970447a7cf0c76028bac (diff)
downloadrust-b17491c8f6d555386104dfd82004c01bfef09c95.tar.gz
rust-b17491c8f6d555386104dfd82004c01bfef09c95.zip
Auto merge of #110211 - joboet:queue_lock, r=Amanieu
Replace pthread `RwLock` with custom implementation

This is one of the last items in #93740. I'm doing `RwLock` first because it is more self-contained and has less tradeoffs to make. The motivation is explained in the documentation, but in short: the pthread rwlock is slow and buggy and `std` can do much better. I considered implementing a parking lot, as was discussed in the tracking issue, but settled for the queue-based version because writing self-balancing binary trees is not fun in Rust...

This is a rather complex change, so I have added quite a bit of documentation to help explain it. Please point out any part that could be explained better.

~~The read performance is really good, I'm getting 4x the throughput of the pthread version and about the same performance as usync/parking_lot on an Apple M1 Max in the usync benchmark suite, but the write performance still falls way behind what usync and parking_lot achieve. I tried using a separate queue lock like what usync uses, but that didn't help. I'll try to investigate further in the future, but I wanted to get some eyes on this first.~~ [Resolved](https://github.com/rust-lang/rust/pull/110211#issuecomment-1513682336)

r? `@m-ou-se`
CC `@kprotty`
Diffstat (limited to 'library/std/src/thread')
-rw-r--r--library/std/src/thread/mod.rs11
1 files changed, 10 insertions, 1 deletions
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 8498937809e..eb837c8f6c6 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -1063,7 +1063,7 @@ pub fn park() {
     let guard = PanicGuard;
     // SAFETY: park_timeout is called on the parker owned by this thread.
     unsafe {
-        current().inner.as_ref().parker().park();
+        current().park();
     }
     // No panic occurred, do not abort.
     forget(guard);
@@ -1290,6 +1290,15 @@ impl Thread {
         Thread { inner }
     }
 
+    /// Like the public [`park`], but callable on any handle. This is used to
+    /// allow parking in TLS destructors.
+    ///
+    /// # Safety
+    /// May only be called from the thread to which this handle belongs.
+    pub(crate) unsafe fn park(&self) {
+        unsafe { self.inner.as_ref().parker().park() }
+    }
+
     /// Atomically makes the handle's token available if it is not already.
     ///
     /// Every thread is equipped with some basic low-level blocking support, via