about summary refs log tree commit diff
path: root/library/std/src/thread
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-10-15 15:45:30 +0530
committerGitHub <noreply@github.com>2022-10-15 15:45:30 +0530
commitcbe5e7bc623f498426fe27f717a035fcbaebee20 (patch)
tree4dec736abd78a4fd2d137bbe5da0ec5393623931 /library/std/src/thread
parent46244f335b5262ef9bdc34cc564b4dea221948f6 (diff)
parentc320ab98ff1d4adb32cece206aa895e4effae175 (diff)
downloadrust-cbe5e7bc623f498426fe27f717a035fcbaebee20.tar.gz
rust-cbe5e7bc623f498426fe27f717a035fcbaebee20.zip
Rollup merge of #102773 - joboet:apple_parker, r=thomcc
Use semaphores for thread parking on Apple platforms

Currently we use a mutex-condvar pair for thread parking on Apple systems. Unfortunately, `pthread_cond_timedwait` uses the real-time clock for measuring time, which causes problems when the system time changes. The parking implementation in this PR uses a semaphore instead, which measures monotonic time by default, avoiding these issues. As a further benefit, this has the potential to improve performance a bit, since `unpark` does not need to wait for a lock to be released.

Since the Mach semaphores are poorly documented (I could not find availability or stability guarantees for instance), this uses a [dispatch semaphore](https://developer.apple.com/documentation/dispatch/dispatch_semaphore?language=objc) instead. While it adds a layer of indirection (it uses Mach semaphores internally), the overhead is probably negligible.

Tested on macOS 12.5.

r? ``````@thomcc``````
Diffstat (limited to 'library/std/src/thread')
-rw-r--r--library/std/src/thread/tests.rs22
1 files changed, 22 insertions, 0 deletions
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 130e47c8d44..dfb8765ab4e 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -245,6 +245,28 @@ fn test_try_panic_any_message_unit_struct() {
 }
 
 #[test]
+fn test_park_unpark_before() {
+    for _ in 0..10 {
+        thread::current().unpark();
+        thread::park();
+    }
+}
+
+#[test]
+fn test_park_unpark_called_other_thread() {
+    for _ in 0..10 {
+        let th = thread::current();
+
+        let _guard = thread::spawn(move || {
+            super::sleep(Duration::from_millis(50));
+            th.unpark();
+        });
+
+        thread::park();
+    }
+}
+
+#[test]
 fn test_park_timeout_unpark_before() {
     for _ in 0..10 {
         thread::current().unpark();