about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe8472 <git@infinite-source.de>2021-02-20 22:45:30 +0100
committerThe8472 <git@infinite-source.de>2021-03-01 19:47:41 +0100
commit77d1185f00699236c4caec6504d758644d747453 (patch)
tree3adb9e320f28084c8674915a03d0db7be54c21ac
parent5233edcf1c7ee70ac25e4ec1115c3546f53d8a2d (diff)
downloadrust-77d1185f00699236c4caec6504d758644d747453.tar.gz
rust-77d1185f00699236c4caec6504d758644d747453.zip
parallelize tidy checks
-rw-r--r--Cargo.lock1
-rw-r--r--src/tools/tidy/Cargo.toml1
-rw-r--r--src/tools/tidy/src/bins.rs7
-rw-r--r--src/tools/tidy/src/lib.rs7
-rw-r--r--src/tools/tidy/src/main.rs99
5 files changed, 76 insertions, 39 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6e95fd6af27..2f2d9065511 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5239,6 +5239,7 @@ name = "tidy"
 version = "0.1.0"
 dependencies = [
  "cargo_metadata 0.11.1",
+ "crossbeam-utils 0.8.0",
  "lazy_static",
  "regex",
  "walkdir",
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 777d7be8fdc..58c32993cb6 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -10,6 +10,7 @@ cargo_metadata = "0.11"
 regex = "1"
 lazy_static = "1"
 walkdir = "2"
+crossbeam-utils = "0.8.0"
 
 [[bin]]
 name = "rust-tidy"
diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs
index 62cfa85577f..f4e203cac40 100644
--- a/src/tools/tidy/src/bins.rs
+++ b/src/tools/tidy/src/bins.rs
@@ -32,9 +32,12 @@ pub fn check(path: &Path, output: &Path, bad: &mut bool) {
     // readily create a file there to test.
     //
     // See #36706 and #74753 for context.
-    let mut temp_path = path.join("tidy-test-file");
+    //
+    // We also add the thread ID to avoid threads trampling on each others files.
+    let file_name = format!("t{}.tidy-test-file", std::thread::current().id().as_u64());
+    let mut temp_path = path.join(&file_name);
     match fs::File::create(&temp_path).or_else(|_| {
-        temp_path = output.join("tidy-test-file");
+        temp_path = output.join(&file_name);
         fs::File::create(&temp_path)
     }) {
         Ok(file) => {
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 11d36751f67..45cc169470b 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -4,6 +4,7 @@
 //! to be used by tools.
 
 #![cfg_attr(bootstrap, feature(str_split_once))]
+#![feature(thread_id_value)]
 
 use std::fs::File;
 use std::io::Read;
@@ -54,6 +55,12 @@ pub mod unit_tests;
 pub mod unstable_book;
 
 fn filter_dirs(path: &Path) -> bool {
+    // Filter out temporary files used by the bins module to probe the filesystem
+    match path.extension() {
+        Some(ext) if ext == "tidy-test-file" => return true,
+        _ => {}
+    }
+
     let skip = [
         "compiler/rustc_codegen_cranelift",
         "src/llvm-project",
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 2ac96e404ac..9151d2bb406 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -6,9 +6,11 @@
 
 use tidy::*;
 
+use crossbeam_utils::thread::scope;
 use std::env;
 use std::path::PathBuf;
 use std::process;
+use std::sync::atomic::{AtomicBool, Ordering};
 
 fn main() {
     let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
@@ -22,45 +24,68 @@ fn main() {
 
     let args: Vec<String> = env::args().skip(1).collect();
 
-    let mut bad = false;
     let verbose = args.iter().any(|s| *s == "--verbose");
 
-    // Checks over tests.
-    debug_artifacts::check(&src_path, &mut bad);
-    ui_tests::check(&src_path, &mut bad);
-
-    // Checks that only make sense for the compiler.
-    errors::check(&compiler_path, &mut bad);
-    error_codes_check::check(&src_path, &mut bad);
-
-    // Checks that only make sense for the std libs.
-    pal::check(&library_path, &mut bad);
-
-    // Checks that need to be done for both the compiler and std libraries.
-    unit_tests::check(&src_path, &mut bad);
-    unit_tests::check(&compiler_path, &mut bad);
-    unit_tests::check(&library_path, &mut bad);
-
-    bins::check(&src_path, &output_directory, &mut bad);
-    bins::check(&compiler_path, &output_directory, &mut bad);
-    bins::check(&library_path, &output_directory, &mut bad);
-
-    style::check(&src_path, &mut bad);
-    style::check(&compiler_path, &mut bad);
-    style::check(&library_path, &mut bad);
-
-    edition::check(&src_path, &mut bad);
-    edition::check(&compiler_path, &mut bad);
-    edition::check(&library_path, &mut bad);
-
-    let collected = features::check(&src_path, &compiler_path, &library_path, &mut bad, verbose);
-    unstable_book::check(&src_path, collected, &mut bad);
-
-    // Checks that are done on the cargo workspace.
-    deps::check(&root_path, &cargo, &mut bad);
-    extdeps::check(&root_path, &mut bad);
-
-    if bad {
+    let bad = std::sync::Arc::new(AtomicBool::new(false));
+
+    scope(|s| {
+        macro_rules! check {
+            ($p:ident $(, $args:expr)* ) => {
+                s.spawn(|_| {
+                    let mut flag = false;
+                    $p::check($($args),* , &mut flag);
+                    if (flag) {
+                        bad.store(true, Ordering::Relaxed);
+                    }
+                });
+            }
+        }
+
+        // Checks that are done on the cargo workspace.
+        check!(deps, &root_path, &cargo);
+        check!(extdeps, &root_path);
+
+        // Checks over tests.
+        check!(debug_artifacts, &src_path);
+        check!(ui_tests, &src_path);
+
+        // Checks that only make sense for the compiler.
+        check!(errors, &compiler_path);
+        check!(error_codes_check, &src_path);
+
+        // Checks that only make sense for the std libs.
+        check!(pal, &library_path);
+
+        // Checks that need to be done for both the compiler and std libraries.
+        check!(unit_tests, &src_path);
+        check!(unit_tests, &compiler_path);
+        check!(unit_tests, &library_path);
+
+        check!(bins, &src_path, &output_directory);
+        check!(bins, &compiler_path, &output_directory);
+        check!(bins, &library_path, &output_directory);
+
+        check!(style, &src_path);
+        check!(style, &compiler_path);
+        check!(style, &library_path);
+
+        check!(edition, &src_path);
+        check!(edition, &compiler_path);
+        check!(edition, &library_path);
+
+        let collected = {
+            let mut flag = false;
+            let r = features::check(&src_path, &compiler_path, &library_path, &mut flag, verbose);
+            if flag {
+                bad.store(true, Ordering::Relaxed);
+            }
+            r
+        };
+        check!(unstable_book, &src_path, collected);
+    })
+    .unwrap();
+
+    if bad.load(Ordering::Relaxed) {
         eprintln!("some tidy checks failed");
         process::exit(1);
     }