Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit aba227b

Browse files
Rollup merge of rust-lang#131954 - the8472:bootstrap-parallel-git, r=Kobzol
shave 150ms off bootstrap This starts `git` commands inside `GitInfo`and the submodule updates in parallel. Git should already perform internal locking in cases where it needs to serialize a modification. ``` OLD Benchmark #1: ./x check core Time (mean ± σ): 608.7 ms ± 4.4 ms [User: 368.3 ms, System: 455.1 ms] Range (min ... max): 602.3 ms ... 618.8 ms 10 runs NEW Benchmark #1: ./x check core Time (mean ± σ): 462.8 ms ± 2.6 ms [User: 350.2 ms, System: 485.1 ms] Range (min ... max): 457.5 ms ... 465.6 ms 10 runs ``` This should help with the rust-analyzer setup which issues many individual `./x check` calls. There's more that could be done but these were the lowest-hanging fruits that I saw.
2 parents 1b24c6f + a269e4d commit aba227b

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

‎src/bootstrap/src/lib.rs‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -545,23 +545,28 @@ impl Build {
545545
.args(["--get-regexp", "path"])
546546
.run_capture(self)
547547
.stdout();
548-
for line in output.lines() {
548+
std::thread::scope(|s| {
549549
// Look for `submodule.$name.path = $path`
550550
// Sample output: `submodule.src/rust-installer.path src/tools/rust-installer`
551-
let submodule = line.split_once(' ').unwrap().1;
552-
self.update_existing_submodule(submodule);
553-
}
551+
for line in output.lines() {
552+
let submodule = line.split_once(' ').unwrap().1;
553+
let config = self.config.clone();
554+
s.spawn(move || {
555+
Self::update_existing_submodule(&config, submodule);
556+
});
557+
}
558+
});
554559
}
555560

556561
/// Updates the given submodule only if it's initialized already; nothing happens otherwise.
557-
pub fn update_existing_submodule(&self, submodule: &str) {
562+
pub fn update_existing_submodule(config:&Config, submodule: &str) {
558563
// Avoid running git when there isn't a git checkout.
559-
if !self.config.submodules() {
564+
if !config.submodules() {
560565
return;
561566
}
562567

563568
if GitInfo::new(false, Path::new(submodule)).is_managed_git_subrepository() {
564-
self.config.update_submodule(submodule);
569+
config.update_submodule(submodule);
565570
}
566571
}
567572

‎src/bootstrap/src/utils/channel.rs‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::path::Path;
1010

1111
use super::helpers;
1212
use crate::Build;
13-
use crate::utils::helpers::{output, t};
13+
use crate::utils::helpers::{start_process, t};
1414

1515
#[derive(Clone, Default)]
1616
pub enum GitInfo {
@@ -56,7 +56,7 @@ impl GitInfo {
5656
}
5757

5858
// Ok, let's scrape some info
59-
let ver_date = output(
59+
let ver_date = start_process(
6060
helpers::git(Some(dir))
6161
.arg("log")
6262
.arg("-1")
@@ -65,14 +65,14 @@ impl GitInfo {
6565
.as_command_mut(),
6666
);
6767
let ver_hash =
68-
output(helpers::git(Some(dir)).arg("rev-parse").arg("HEAD").as_command_mut());
69-
let short_ver_hash = output(
68+
start_process(helpers::git(Some(dir)).arg("rev-parse").arg("HEAD").as_command_mut());
69+
let short_ver_hash = start_process(
7070
helpers::git(Some(dir)).arg("rev-parse").arg("--short=9").arg("HEAD").as_command_mut(),
7171
);
7272
GitInfo::Present(Some(Info {
73-
commit_date: ver_date.trim().to_string(),
74-
sha: ver_hash.trim().to_string(),
75-
short_sha: short_ver_hash.trim().to_string(),
73+
commit_date: ver_date().trim().to_string(),
74+
sha: ver_hash().trim().to_string(),
75+
short_sha: short_ver_hash().trim().to_string(),
7676
}))
7777
}
7878

‎src/bootstrap/src/utils/helpers.rs‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,33 @@ pub fn output(cmd: &mut Command) -> String {
288288
String::from_utf8(output.stdout).unwrap()
289289
}
290290

291+
/// Spawn a process and return a closure that will wait for the process
292+
/// to finish and then return its output. This allows the spawned process
293+
/// to do work without immediately blocking bootstrap.
294+
#[track_caller]
295+
pub fn start_process(cmd: &mut Command) -> impl FnOnce() -> String {
296+
let child = match cmd.stderr(Stdio::inherit()).stdout(Stdio::piped()).spawn() {
297+
Ok(child) => child,
298+
Err(e) => fail(&format!("failed to execute command: {cmd:?}\nERROR: {e}")),
299+
};
300+
301+
let command = format!("{:?}", cmd);
302+
303+
move || {
304+
let output = child.wait_with_output().unwrap();
305+
306+
if !output.status.success() {
307+
panic!(
308+
"command did not execute successfully: {}\n\
309+
expected success, got: {}",
310+
command, output.status
311+
);
312+
}
313+
314+
String::from_utf8(output.stdout).unwrap()
315+
}
316+
}
317+
291318
/// Returns the last-modified time for `path`, or zero if it doesn't exist.
292319
pub fn mtime(path: &Path) -> SystemTime {
293320
fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /