rustdoc: DocFS: Replace rayon with threadpool and enable it for all targets

This commit is contained in:
Guillaume Gomez 2023-03-14 20:28:00 +01:00
parent 24c0b81c1f
commit 50f7520526
3 changed files with 32 additions and 10 deletions

View File

@ -5457,13 +5457,13 @@ dependencies = [
"itertools", "itertools",
"minifier", "minifier",
"once_cell", "once_cell",
"rayon",
"regex", "regex",
"rustdoc-json-types", "rustdoc-json-types",
"serde", "serde",
"serde_json", "serde_json",
"smallvec", "smallvec",
"tempfile", "tempfile",
"threadpool",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"tracing-tree", "tracing-tree",
@ -6208,6 +6208,15 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "threadpool"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
dependencies = [
"num_cpus",
]
[[package]] [[package]]
name = "tidy" name = "tidy"
version = "0.1.0" version = "0.1.0"

View File

@ -20,15 +20,13 @@ smallvec = "1.8.1"
tempfile = "3" tempfile = "3"
tracing = "0.1" tracing = "0.1"
tracing-tree = "0.2.0" tracing-tree = "0.2.0"
threadpool = "1.8.1"
[dependencies.tracing-subscriber] [dependencies.tracing-subscriber]
version = "0.3.3" version = "0.3.3"
default-features = false default-features = false
features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"]
[target.'cfg(windows)'.dependencies]
rayon = "1.5.1"
[dev-dependencies] [dev-dependencies]
expect-test = "1.4.0" expect-test = "1.4.0"

View File

@ -9,11 +9,14 @@
//! needs to read-after-write from a file, then it would be added to this //! needs to read-after-write from a file, then it would be added to this
//! abstraction. //! abstraction.
use std::cmp::max;
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::string::ToString; use std::string::ToString;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::thread::available_parallelism;
use threadpool::ThreadPool;
pub(crate) trait PathError { pub(crate) trait PathError {
fn new<S, P: AsRef<Path>>(e: S, path: P) -> Self fn new<S, P: AsRef<Path>>(e: S, path: P) -> Self
@ -24,11 +27,21 @@ pub(crate) trait PathError {
pub(crate) struct DocFS { pub(crate) struct DocFS {
sync_only: bool, sync_only: bool,
errors: Option<Sender<String>>, errors: Option<Sender<String>>,
pool: ThreadPool,
} }
impl DocFS { impl DocFS {
pub(crate) fn new(errors: Sender<String>) -> DocFS { pub(crate) fn new(errors: Sender<String>) -> DocFS {
DocFS { sync_only: false, errors: Some(errors) } const MINIMUM_NB_THREADS: usize = 2;
DocFS {
sync_only: false,
errors: Some(errors),
pool: ThreadPool::new(
available_parallelism()
.map(|nb| max(nb.get(), MINIMUM_NB_THREADS))
.unwrap_or(MINIMUM_NB_THREADS),
),
}
} }
pub(crate) fn set_sync_only(&mut self, sync_only: bool) { pub(crate) fn set_sync_only(&mut self, sync_only: bool) {
@ -54,12 +67,11 @@ impl DocFS {
where where
E: PathError, E: PathError,
{ {
#[cfg(windows)]
if !self.sync_only { if !self.sync_only {
// A possible future enhancement after more detailed profiling would // A possible future enhancement after more detailed profiling would
// be to create the file sync so errors are reported eagerly. // be to create the file sync so errors are reported eagerly.
let sender = self.errors.clone().expect("can't write after closing"); let sender = self.errors.clone().expect("can't write after closing");
rayon::spawn(move || { self.pool.execute(move || {
fs::write(&path, contents).unwrap_or_else(|e| { fs::write(&path, contents).unwrap_or_else(|e| {
sender.send(format!("\"{}\": {}", path.display(), e)).unwrap_or_else(|_| { sender.send(format!("\"{}\": {}", path.display(), e)).unwrap_or_else(|_| {
panic!("failed to send error on \"{}\"", path.display()) panic!("failed to send error on \"{}\"", path.display())
@ -70,9 +82,12 @@ impl DocFS {
fs::write(&path, contents).map_err(|e| E::new(e, path))?; fs::write(&path, contents).map_err(|e| E::new(e, path))?;
} }
#[cfg(not(windows))]
fs::write(&path, contents).map_err(|e| E::new(e, path))?;
Ok(()) Ok(())
} }
} }
impl Drop for DocFS {
fn drop(&mut self) {
self.pool.join();
}
}