about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-15 10:48:17 +0000
committerbors <bors@rust-lang.org>2024-09-15 10:48:17 +0000
commit7d8ee712743ae301730fd9228b22e3c913768022 (patch)
treec677f6e5e185775cf57816efa9894e32033cc10f
parent75921d2ca4477819342dea2a428535a565683031 (diff)
parent5f3bec427c1e619dd5bb8d9c4f3d164c6d3d1469 (diff)
downloadrust-7d8ee712743ae301730fd9228b22e3c913768022.tar.gz
rust-7d8ee712743ae301730fd9228b22e3c913768022.zip
Auto merge of #3889 - RalfJung:android-pthread, r=RalfJung
add Android pthread support

Also extend what we test on Solarish / FreeBSD, turns out a few more things are working.
-rw-r--r--src/tools/miri/README.md2
-rwxr-xr-xsrc/tools/miri/ci/ci.sh10
-rw-r--r--src/tools/miri/src/shims/unix/sync.rs12
-rw-r--r--src/tools/miri/test_dependencies/Cargo.lock1
-rw-r--r--src/tools/miri/test_dependencies/Cargo.toml1
-rw-r--r--src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs55
-rw-r--r--src/tools/miri/tests/pass/shims/time-with-isolation.rs4
-rw-r--r--src/tools/miri/tests/pass/shims/time-with-isolation.stdout2
8 files changed, 54 insertions, 33 deletions
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 72555e8c40d..d8636915ea8 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -216,9 +216,9 @@ degree documented below):
 - For every other target with OS `linux`, `macos`, or `windows`, Miri should generally work, but we
   make no promises and we don't run tests for such targets.
 - We have unofficial support (not maintained by the Miri team itself) for some further operating systems.
+  - `solaris` / `illumos`: maintained by @devnexen. Supports `std::{env, thread, sync}`, but not `std::fs`.
   - `freebsd`: **maintainer wanted**. Supports `std::env` and parts of `std::{thread, fs}`, but not `std::sync`.
   - `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works.
-  - `solaris` / `illumos`: maintained by @devnexen. Support very incomplete, but a basic "hello world" works.
   - `wasm`: **maintainer wanted**. Support very incomplete, not even standard output works, but an empty `main` function works.
 - For targets on other operating systems, Miri might fail before even reaching the `main` function.
 
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 6b57a294b65..c7be71662bd 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -150,11 +150,11 @@ case $HOST_TARGET in
     # Partially supported targets (tier 2)
     BASIC="empty_main integer vec string btreemap hello hashmap heap_alloc align" # ensures we have the basics: stdout/stderr, system allocator, randomness (for HashMap initialization)
     UNIX="panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
-    TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname pthread libc-time fs
-    TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX threadname pthread libc-time fs
-    TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX threadname pthread sync available-parallelism libc-time tls
-    TEST_TARGET=x86_64-pc-solaris      run_tests_minimal $BASIC $UNIX threadname pthread sync available-parallelism libc-time tls
-    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX
+    TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname pthread time fs
+    TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX threadname pthread time fs
+    TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX thread sync available-parallelism time tls
+    TEST_TARGET=x86_64-pc-solaris      run_tests_minimal $BASIC $UNIX thread sync available-parallelism time tls
+    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX pthread --skip threadname --skip pthread_cond_timedwait
     TEST_TARGET=wasm32-wasip2          run_tests_minimal empty_main wasm heap_alloc libc-mem
     TEST_TARGET=wasm32-unknown-unknown run_tests_minimal empty_main wasm
     TEST_TARGET=thumbv7em-none-eabihf  run_tests_minimal no_std
diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs
index 114a457d71a..fea994663c0 100644
--- a/src/tools/miri/src/shims/unix/sync.rs
+++ b/src/tools/miri/src/shims/unix/sync.rs
@@ -11,7 +11,7 @@ use crate::*;
 #[inline]
 fn mutexattr_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
     Ok(match &*ecx.tcx.sess.target.os {
-        "linux" | "illumos" | "solaris" | "macos" | "freebsd" => 0,
+        "linux" | "illumos" | "solaris" | "macos" | "freebsd" | "android" => 0,
         os => throw_unsup_format!("`pthread_mutexattr` is not supported on {os}"),
     })
 }
@@ -76,7 +76,7 @@ fn mutex_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
     // When adding a new OS, make sure we also support all its static initializers in
     // `mutex_kind_from_static_initializer`!
     let offset = match &*ecx.tcx.sess.target.os {
-        "linux" | "illumos" | "solaris" | "freebsd" => 0,
+        "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0,
         // macOS stores a signature in the first bytes, so we have to move to offset 4.
         "macos" => 4,
         os => throw_unsup_format!("`pthread_mutex` is not supported on {os}"),
@@ -105,7 +105,7 @@ fn mutex_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
                 check_static_initializer("PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP");
                 check_static_initializer("PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP");
             }
-            "illumos" | "solaris" | "macos" | "freebsd" => {
+            "illumos" | "solaris" | "macos" | "freebsd" | "android" => {
                 // No non-standard initializers.
             }
             os => throw_unsup_format!("`pthread_mutex` is not supported on {os}"),
@@ -216,7 +216,7 @@ pub struct AdditionalRwLockData {
 
 fn rwlock_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
     let offset = match &*ecx.tcx.sess.target.os {
-        "linux" | "illumos" | "solaris" | "freebsd" => 0,
+        "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0,
         // macOS stores a signature in the first bytes, so we have to move to offset 4.
         "macos" => 4,
         os => throw_unsup_format!("`pthread_rwlock` is not supported on {os}"),
@@ -269,7 +269,7 @@ fn rwlock_get_id<'tcx>(
 #[inline]
 fn condattr_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
     Ok(match &*ecx.tcx.sess.target.os {
-        "linux" | "illumos" | "solaris" | "freebsd" => 0,
+        "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0,
         // macOS does not have a clock attribute.
         os => throw_unsup_format!("`pthread_condattr` clock field is not supported on {os}"),
     })
@@ -321,7 +321,7 @@ fn condattr_set_clock_id<'tcx>(
 
 fn cond_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
     let offset = match &*ecx.tcx.sess.target.os {
-        "linux" | "illumos" | "solaris" | "freebsd" => 0,
+        "linux" | "illumos" | "solaris" | "freebsd" | "android" => 0,
         // macOS stores a signature in the first bytes, so we have to move to offset 4.
         "macos" => 4,
         os => throw_unsup_format!("`pthread_cond` is not supported on {os}"),
diff --git a/src/tools/miri/test_dependencies/Cargo.lock b/src/tools/miri/test_dependencies/Cargo.lock
index 39d41281728..9a4431eb704 100644
--- a/src/tools/miri/test_dependencies/Cargo.lock
+++ b/src/tools/miri/test_dependencies/Cargo.lock
@@ -172,6 +172,7 @@ dependencies = [
 name = "miri-test-deps"
 version = "0.1.0"
 dependencies = [
+ "cfg-if",
  "getrandom 0.1.16",
  "getrandom 0.2.15",
  "libc",
diff --git a/src/tools/miri/test_dependencies/Cargo.toml b/src/tools/miri/test_dependencies/Cargo.toml
index c24422df26c..e7eff46afca 100644
--- a/src/tools/miri/test_dependencies/Cargo.toml
+++ b/src/tools/miri/test_dependencies/Cargo.toml
@@ -11,6 +11,7 @@ edition = "2021"
 # all dependencies (and their transitive ones) listed here can be used in `tests/`.
 libc = "0.2"
 num_cpus = "1.10.1"
+cfg-if = "1"
 
 getrandom_01 = { package = "getrandom", version = "0.1" }
 getrandom_02 = { package = "getrandom", version = "0.2", features = ["js"] }
diff --git a/src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs b/src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs
index d66cd3bbb03..8be42b50897 100644
--- a/src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs
+++ b/src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs
@@ -10,16 +10,42 @@ fn main() {
         .collect::<String>();
 
     fn set_thread_name(name: &CStr) -> i32 {
-        #[cfg(any(target_os = "linux", target_os = "illumos", target_os = "solaris"))]
-        return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) };
-        #[cfg(target_os = "freebsd")]
-        unsafe {
-            // pthread_set_name_np does not return anything
-            libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr().cast());
-            return 0;
-        };
-        #[cfg(target_os = "macos")]
-        return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) };
+        cfg_if::cfg_if! {
+            if #[cfg(any(target_os = "linux", target_os = "illumos", target_os = "solaris"))] {
+                unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) }
+            } else if #[cfg(target_os = "freebsd")] {
+                // pthread_set_name_np does not return anything
+                unsafe { libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr().cast()) };
+                0
+            } else if #[cfg(target_os = "macos")] {
+                unsafe { libc::pthread_setname_np(name.as_ptr().cast()) }
+            } else {
+                compile_error!("set_thread_name not supported for this OS")
+            }
+        }
+    }
+
+    fn get_thread_name(name: &mut [u8]) -> i32 {
+        cfg_if::cfg_if! {
+            if #[cfg(any(
+                target_os = "linux",
+                target_os = "illumos",
+                target_os = "solaris",
+                target_os = "macos"
+            ))] {
+                unsafe {
+                    libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
+                }
+            } else if #[cfg(target_os = "freebsd")] {
+                // pthread_get_name_np does not return anything
+                unsafe {
+                    libc::pthread_get_name_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
+                };
+                0
+            } else {
+                compile_error!("get_thread_name not supported for this OS")
+            }
+        }
     }
 
     let result = thread::Builder::new().name(long_name.clone()).spawn(move || {
@@ -28,14 +54,7 @@ fn main() {
 
         // But the system is limited -- make sure we successfully set a truncation.
         let mut buf = vec![0u8; long_name.len() + 1];
-        #[cfg(not(target_os = "freebsd"))]
-        unsafe {
-            libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
-        };
-        #[cfg(target_os = "freebsd")]
-        unsafe {
-            libc::pthread_get_name_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len())
-        };
+        assert_eq!(get_thread_name(&mut buf), 0);
         let cstr = CStr::from_bytes_until_nul(&buf).unwrap();
         assert!(cstr.to_bytes().len() >= 15, "name is too short: len={}", cstr.to_bytes().len()); // POSIX seems to promise at least 15 chars
         assert!(long_name.as_bytes().starts_with(cstr.to_bytes()));
diff --git a/src/tools/miri/tests/pass/shims/time-with-isolation.rs b/src/tools/miri/tests/pass/shims/time-with-isolation.rs
index 645d42ad975..e7b16244123 100644
--- a/src/tools/miri/tests/pass/shims/time-with-isolation.rs
+++ b/src/tools/miri/tests/pass/shims/time-with-isolation.rs
@@ -41,9 +41,9 @@ fn test_block_for_one_second() {
 /// Ensures that we get the same behavior across all targets.
 fn test_deterministic() {
     let begin = Instant::now();
-    for _ in 0..100_000 {}
+    for _ in 0..10_000 {}
     let time = begin.elapsed();
-    println!("The loop took around {}s", time.as_secs());
+    println!("The loop took around {}ms", time.as_millis());
     println!("(It's fine for this number to change when you `--bless` this test.)")
 }
 
diff --git a/src/tools/miri/tests/pass/shims/time-with-isolation.stdout b/src/tools/miri/tests/pass/shims/time-with-isolation.stdout
index ff5889bacd5..2d7fb5f4a61 100644
--- a/src/tools/miri/tests/pass/shims/time-with-isolation.stdout
+++ b/src/tools/miri/tests/pass/shims/time-with-isolation.stdout
@@ -1,2 +1,2 @@
-The loop took around 12s
+The loop took around 1250ms
 (It's fine for this number to change when you `--bless` this test.)