From 3bb40f2ea00ceac3e91986a01ef5b2ecc8070f29 Mon Sep 17 00:00:00 2001 From: Chris Palmer Date: Tue, 19 Oct 2021 20:40:09 -0700 Subject: [PATCH 1/8] Make printed message match the code comment I think this code is getting L0, not L1 cache size, if I'm reading the Intel manual right. (I might not be.) Either way, the code comment and the printed message should match, whichever way is right. :) --- src/doc/unstable-book/src/library-features/asm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 5a2cef24870be..e70933b7bae10 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -257,7 +257,7 @@ unsafe { } println!( - "L1 Cache: {}", + "L0 Cache: {}", ((ebx >> 22) + 1) * (((ebx >> 12) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1) ); ``` From 01e441f8e51a8276ccbc3bda6ac616eac13d01b4 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Wed, 27 Oct 2021 22:18:51 +0200 Subject: [PATCH 2/8] Document clippy on nightly-rustc --- src/bootstrap/builder.rs | 1 + src/bootstrap/doc.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d5656f0f37e03..6ba1b1b6036ea 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -482,6 +482,7 @@ impl<'a> Builder<'a> { doc::RustByExample, doc::RustcBook, doc::CargoBook, + doc::Clippy, doc::EmbeddedBook, doc::EditionGuide, ), diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 6f2470b706a64..2804e7119fbc1 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -755,6 +755,7 @@ tool_doc!( "src/tools/rustfmt", ["rustfmt-nightly", "rustfmt-config_proc_macro"], ); +tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"]); #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ErrorIndex { From d718b1a79508169f10cd4b691071d4308ac15fc3 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 31 Oct 2021 15:02:38 +0100 Subject: [PATCH 3/8] Add JoinHandle::is_running. --- library/std/src/thread/mod.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 0c1ffeb1a79a4..f8f6411711311 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1402,6 +1402,15 @@ impl JoinHandle { pub fn join(mut self) -> Result { self.0.join() } + + /// Checks if the the associated thread is still running its main function. + /// + /// This might return `false` for a brief moment after the thread's main + /// function has returned, but before the thread itself has stopped running. + #[unstable(feature = "thread_is_running", issue = "none")] + pub fn is_running(&self) -> bool { + Arc::strong_count(&self.0.packet.0) > 1 + } } impl AsInner for JoinHandle { From 67362b301bd00802c10c9fa9bc7396dc7ada83dd Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 31 Oct 2021 15:02:49 +0100 Subject: [PATCH 4/8] Add test for JoinHandle::is_running. --- library/std/src/thread/tests.rs | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 16ad366fc126a..ca0d88135a5d8 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -2,9 +2,13 @@ use super::Builder; use crate::any::Any; use crate::mem; use crate::result; -use crate::sync::mpsc::{channel, Sender}; +use crate::sync::{ + mpsc::{channel, Sender}, + Arc, Barrier, +}; use crate::thread::{self, ThreadId}; use crate::time::Duration; +use crate::time::Instant; // !!! These tests are dangerous. If something is buggy, they will hang, !!! // !!! instead of exiting cleanly. This might wedge the buildbots. !!! @@ -46,6 +50,36 @@ fn test_run_basic() { rx.recv().unwrap(); } +#[test] +fn test_is_running() { + let b = Arc::new(Barrier::new(2)); + let t = thread::spawn({ + let b = b.clone(); + move || { + b.wait(); + 1234 + } + }); + + // Thread is definitely running here, since it's still waiting for the barrier. + assert_eq!(t.is_running(), true); + + // Unblock the barrier. + b.wait(); + + // Now check that t.is_running() becomes false within a reasonable time. + let start = Instant::now(); + while t.is_running() { + assert!(start.elapsed() < Duration::from_secs(2)); + thread::sleep(Duration::from_millis(15)); + } + + // Joining the thread should not block for a significant time now. + let join_time = Instant::now(); + assert_eq!(t.join().unwrap(), 1234); + assert!(join_time.elapsed() < Duration::from_secs(2)); +} + #[test] fn test_join_panic() { match thread::spawn(move || panic!()).join() { From 9212f4070ecaf4277de5f268f2ddfe56585be745 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 31 Oct 2021 16:08:12 +0000 Subject: [PATCH 5/8] Windows thread-local keyless drop `#[thread_local]` allows us to maintain a per-thread list of destructors. This also avoids the need to synchronize global data (which is particularly tricky within the TLS callback function). --- .../std/src/sys/windows/thread_local_dtor.rs | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/windows/thread_local_dtor.rs b/library/std/src/sys/windows/thread_local_dtor.rs index 7be13bc4b2bc7..bf865e0fd7274 100644 --- a/library/std/src/sys/windows/thread_local_dtor.rs +++ b/library/std/src/sys/windows/thread_local_dtor.rs @@ -1,4 +1,39 @@ +//! Implements thread-local destructors that are not associated with any +//! particular data. + #![unstable(feature = "thread_local_internals", issue = "none")] #![cfg(target_thread_local)] +use super::c; + +// Using a per-thread list avoids the problems in synchronizing global state. +#[thread_local] +static mut DESTRUCTORS: Vec<(*mut u8, unsafe extern "C" fn(*mut u8))> = Vec::new(); + +pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { + DESTRUCTORS.push((t, dtor)); +} + +// See windows/thread_local_keys.rs for an explanation of this callback function. +// The short version is that all the function pointers in the `.CRT$XL*` array +// will be called whenever a thread or process starts or ends. + +#[link_section = ".CRT$XLD"] +#[doc(hidden)] +#[used] +pub static TLS_CALLBACK: unsafe extern "system" fn(c::LPVOID, c::DWORD, c::LPVOID) = tls_callback; -pub use crate::sys_common::thread_local_dtor::register_dtor_fallback as register_dtor; +unsafe extern "system" fn tls_callback(_: c::LPVOID, reason: c::DWORD, _: c::LPVOID) { + if reason == c::DLL_THREAD_DETACH || reason == c::DLL_PROCESS_DETACH { + // Drop all the destructors. + // + // Note: While this is potentially an infinite loop, it *should* be + // the case that this loop always terminates because we provide the + // guarantee that a TLS key cannot be set after it is flagged for + // destruction. + while let Some((ptr, dtor)) = DESTRUCTORS.pop() { + (dtor)(ptr); + } + // We're done so free the memory. + DESTRUCTORS.shrink_to_fit(); + } +} From 978ebd9c8cd91079be62656ca193a9cbc85e157b Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 1 Nov 2021 15:04:24 +0100 Subject: [PATCH 6/8] Add tracking issue for thread_is_running. --- library/std/src/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index f8f6411711311..12d9f955bb767 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1407,7 +1407,7 @@ impl JoinHandle { /// /// This might return `false` for a brief moment after the thread's main /// function has returned, but before the thread itself has stopped running. - #[unstable(feature = "thread_is_running", issue = "none")] + #[unstable(feature = "thread_is_running", issue = "90470")] pub fn is_running(&self) -> bool { Arc::strong_count(&self.0.packet.0) > 1 } From 1048651fa3d0c8d5ac98a616810d1cf2b1fe80c0 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 1 Nov 2021 15:05:57 +0000 Subject: [PATCH 7/8] Run destructors from existing tls callback --- .../std/src/sys/windows/thread_local_dtor.rs | 35 +++++++------------ .../std/src/sys/windows/thread_local_key.rs | 2 ++ 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/library/std/src/sys/windows/thread_local_dtor.rs b/library/std/src/sys/windows/thread_local_dtor.rs index bf865e0fd7274..25d1c6e8e87c2 100644 --- a/library/std/src/sys/windows/thread_local_dtor.rs +++ b/library/std/src/sys/windows/thread_local_dtor.rs @@ -3,7 +3,6 @@ #![unstable(feature = "thread_local_internals", issue = "none")] #![cfg(target_thread_local)] -use super::c; // Using a per-thread list avoids the problems in synchronizing global state. #[thread_local] @@ -13,27 +12,17 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { DESTRUCTORS.push((t, dtor)); } -// See windows/thread_local_keys.rs for an explanation of this callback function. -// The short version is that all the function pointers in the `.CRT$XL*` array -// will be called whenever a thread or process starts or ends. - -#[link_section = ".CRT$XLD"] -#[doc(hidden)] -#[used] -pub static TLS_CALLBACK: unsafe extern "system" fn(c::LPVOID, c::DWORD, c::LPVOID) = tls_callback; - -unsafe extern "system" fn tls_callback(_: c::LPVOID, reason: c::DWORD, _: c::LPVOID) { - if reason == c::DLL_THREAD_DETACH || reason == c::DLL_PROCESS_DETACH { - // Drop all the destructors. - // - // Note: While this is potentially an infinite loop, it *should* be - // the case that this loop always terminates because we provide the - // guarantee that a TLS key cannot be set after it is flagged for - // destruction. - while let Some((ptr, dtor)) = DESTRUCTORS.pop() { - (dtor)(ptr); - } - // We're done so free the memory. - DESTRUCTORS.shrink_to_fit(); +/// Runs destructors. This should not be called until thread exit. +pub unsafe fn run_keyless_dtors() { + // Drop all the destructors. + // + // Note: While this is potentially an infinite loop, it *should* be + // the case that this loop always terminates because we provide the + // guarantee that a TLS key cannot be set after it is flagged for + // destruction. + while let Some((ptr, dtor)) = DESTRUCTORS.pop() { + (dtor)(ptr); } + // We're done so free the memory. + DESTRUCTORS = Vec::new(); } diff --git a/library/std/src/sys/windows/thread_local_key.rs b/library/std/src/sys/windows/thread_local_key.rs index 0bc511146654b..ec670238e6f0e 100644 --- a/library/std/src/sys/windows/thread_local_key.rs +++ b/library/std/src/sys/windows/thread_local_key.rs @@ -196,6 +196,8 @@ pub static p_thread_callback: unsafe extern "system" fn(c::LPVOID, c::DWORD, c:: unsafe extern "system" fn on_tls_callback(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID) { if dwReason == c::DLL_THREAD_DETACH || dwReason == c::DLL_PROCESS_DETACH { run_dtors(); + #[cfg(target_thread_local)] + super::thread_local_dtor::run_keyless_dtors(); } // See comments above for what this is doing. Note that we don't need this From 37476287bf099a8f8a21342fb5f371379b523cef Mon Sep 17 00:00:00 2001 From: Hans Kratz Date: Mon, 1 Nov 2021 17:03:07 +0100 Subject: [PATCH 8/8] Use apple-a14 as target CPU for aarch64-apple-darwin. After updating the minimum required LLVM version to 12 we can use apple-a14 as that is closer in features to the Apple M1 than the A12. Once the minimum required LLVM version is updated to 13 we can use apple-m1. --- compiler/rustc_target/src/spec/aarch64_apple_darwin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index 2c71fb8afeede..ca3550e9278d1 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs @@ -2,7 +2,7 @@ use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, Target, TargetOption pub fn target() -> Target { let mut base = super::apple_base::opts("macos"); - base.cpu = "apple-a12".to_string(); + base.cpu = "apple-a14".to_string(); base.max_atomic_width = Some(128); // FIXME: The leak sanitizer currently fails the tests, see #88132.