Skip to content

Commit 1020ed3

Browse files
authored
Rollup merge of #82532 - pnkfelix:rustbuild-print-step-rusage, r=Mark-Simulacrum
Add `build.print_step_rusage` to config.toml Adds `build.print_step_rusage` to config.toml, which is meant to be an easy way to let compiler developers get feedback on the terminal during bootstrap about resource usage during each step. The output is piggy-backed on `[PRINT-STEP-TIMINGS]`, mostly because the functionality seemed to naturally fit there in the overall control-flow and output structure (even if very little is shared between the implementations themselves). Some sample output (from my Linux box, where I believe the `max rss` output to be somewhat trust-worthy...): ``` [...] Compiling regex v1.4.3 [RUSTC-TIMING] tempfile test:false 0.323 user: 1.418662 sys: 0.81767 max rss (kb): 182084 page reclaims: 26615 page faults: 0 fs block inputs: 0 fs block outputs: 2160 voluntary ctxt switches: 798 involuntary ctxt switches: 131 Completed tempfile v3.1.0 in 0.3s [RUSTC-TIMING] chalk_ir test:false 1.890 user: 1.893603 sys: 0.99663 max rss (kb): 239432 page reclaims: 32107 page faults: 0 fs block inputs: 0 fs block outputs: 25008 voluntary ctxt switches: 108 involuntary ctxt switches: 183 Completed chalk-ir v0.55.0 in 1.9s Compiling rustc_data_structures v0.0.0 (/home/pnkfelix/Dev/Rust/rust.git/compiler/rustc_data_structures) [RUSTC-TIMING] chrono test:false 1.244 user: 3.333198 sys: 0.134963 max rss (kb): 246612 page reclaims: 44857 page faults: 0 fs block inputs: 0 fs block outputs: 11704 voluntary ctxt switches: 1043 involuntary ctxt switches: 326 Completed chrono v0.4.15 in 1.3s [RUSTC-TIMING] rustc_rayon test:false 1.332 user: 1.763912 sys: 0.75996 max rss (kb): 239076 page reclaims: 35285 page faults: 0 fs block inputs: 0 fs block outputs: 19576 voluntary ctxt switches: 359 involuntary ctxt switches: 168 Completed rustc-rayon v0.3.0 in 1.3s Compiling matchers v0.0.1 [RUSTC-TIMING] matchers test:false 0.100 user: 0.94495 sys: 0.15119 max rss (kb): 140076 page reclaims: 8200 page faults: 0 fs block inputs: 0 fs block outputs: 392 voluntary ctxt switches: 43 involuntary ctxt switches: 12 Completed matchers v0.0.1 in 0.1s [...] ```
2 parents a95c3f7 + f2d70c5 commit 1020ed3

File tree

4 files changed

+92
-3
lines changed

4 files changed

+92
-3
lines changed

config.toml.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@ changelog-seen = 2
290290
# tracking over time)
291291
#print-step-timings = false
292292

293+
# Print out resource usage data for each rustbuild step, as defined by the Unix
294+
# struct rusage. (Note that this setting is completely unstable: the data it
295+
# captures, what platforms it supports, the format of its associated output, and
296+
# this setting's very existence, are all subject to change.)
297+
#print-step-rusage = false
298+
293299
# =============================================================================
294300
# General install configuration options
295301
# =============================================================================

src/bootstrap/bin/rustc.rs

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,24 @@ fn main() {
161161
cmd.status().expect(&errmsg)
162162
};
163163

164-
if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some() {
164+
if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some()
165+
|| env::var_os("RUSTC_PRINT_STEP_RUSAGE").is_some()
166+
{
165167
if let Some(crate_name) = crate_name {
166168
let dur = start.elapsed();
167169
let is_test = args.iter().any(|a| a == "--test");
170+
// If the user requested resource usage data, then
171+
// include that in addition to the timing output.
172+
let rusage_data =
173+
env::var_os("RUSTC_PRINT_STEP_RUSAGE").and_then(|_| format_rusage_data());
168174
eprintln!(
169-
"[RUSTC-TIMING] {} test:{} {}.{:03}",
175+
"[RUSTC-TIMING] {} test:{} {}.{:03}{}{}",
170176
crate_name,
171177
is_test,
172178
dur.as_secs(),
173-
dur.subsec_millis()
179+
dur.subsec_millis(),
180+
if rusage_data.is_some() { " " } else { "" },
181+
rusage_data.unwrap_or(String::new()),
174182
);
175183
}
176184
}
@@ -198,3 +206,71 @@ fn main() {
198206
}
199207
}
200208
}
209+
210+
#[cfg(not(unix))]
211+
/// getrusage is not available on non-unix platforms. So for now, we do not
212+
/// bother trying to make a shim for it.
213+
fn format_rusage_data() -> Option<String> {
214+
None
215+
}
216+
217+
#[cfg(unix)]
218+
/// Tries to build a string with human readable data for several of the rusage
219+
/// fields. Note that we are focusing mainly on data that we believe to be
220+
/// supplied on Linux (the `rusage` struct has other fields in it but they are
221+
/// currently unsupported by Linux).
222+
fn format_rusage_data() -> Option<String> {
223+
let rusage: libc::rusage = unsafe {
224+
let mut recv = std::mem::zeroed();
225+
// -1 is RUSAGE_CHILDREN, which means to get the rusage for all children
226+
// (and grandchildren, etc) processes that have respectively terminated
227+
// and been waited for.
228+
let retval = libc::getrusage(-1, &mut recv);
229+
if retval != 0 {
230+
return None;
231+
}
232+
recv
233+
};
234+
// Mac OS X reports the maxrss in bytes, not kb.
235+
let divisor = if env::consts::OS == "macos" { 1024 } else { 1 };
236+
let maxrss = rusage.ru_maxrss + (divisor - 1) / divisor;
237+
238+
let mut init_str = format!(
239+
"user: {USER_SEC}.{USER_USEC:03} \
240+
sys: {SYS_SEC}.{SYS_USEC:03} \
241+
max rss (kb): {MAXRSS}",
242+
USER_SEC = rusage.ru_utime.tv_sec,
243+
USER_USEC = rusage.ru_utime.tv_usec,
244+
SYS_SEC = rusage.ru_stime.tv_sec,
245+
SYS_USEC = rusage.ru_stime.tv_usec,
246+
MAXRSS = maxrss
247+
);
248+
249+
// The remaining rusage stats vary in platform support. So we treat
250+
// uniformly zero values in each category as "not worth printing", since it
251+
// either means no events of that type occurred, or that the platform
252+
// does not support it.
253+
254+
let minflt = rusage.ru_minflt;
255+
let majflt = rusage.ru_majflt;
256+
if minflt != 0 || majflt != 0 {
257+
init_str.push_str(&format!(" page reclaims: {} page faults: {}", minflt, majflt));
258+
}
259+
260+
let inblock = rusage.ru_inblock;
261+
let oublock = rusage.ru_oublock;
262+
if inblock != 0 || oublock != 0 {
263+
init_str.push_str(&format!(" fs block inputs: {} fs block outputs: {}", inblock, oublock));
264+
}
265+
266+
let nvcsw = rusage.ru_nvcsw;
267+
let nivcsw = rusage.ru_nivcsw;
268+
if nvcsw != 0 || nivcsw != 0 {
269+
init_str.push_str(&format!(
270+
" voluntary ctxt switches: {} involuntary ctxt switches: {}",
271+
nvcsw, nivcsw
272+
));
273+
}
274+
275+
return Some(init_str);
276+
}

src/bootstrap/builder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,10 @@ impl<'a> Builder<'a> {
12651265
cargo.env("RUSTC_PRINT_STEP_TIMINGS", "1");
12661266
}
12671267

1268+
if self.config.print_step_rusage {
1269+
cargo.env("RUSTC_PRINT_STEP_RUSAGE", "1");
1270+
}
1271+
12681272
if self.config.backtrace_on_ice {
12691273
cargo.env("RUSTC_BACKTRACE_ON_ICE", "1");
12701274
}

src/bootstrap/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ pub struct Config {
161161
pub verbose_tests: bool,
162162
pub save_toolstates: Option<PathBuf>,
163163
pub print_step_timings: bool,
164+
pub print_step_rusage: bool,
164165
pub missing_tools: bool,
165166

166167
// Fallback musl-root for all targets
@@ -380,6 +381,7 @@ struct Build {
380381
configure_args: Option<Vec<String>>,
381382
local_rebuild: Option<bool>,
382383
print_step_timings: Option<bool>,
384+
print_step_rusage: Option<bool>,
383385
check_stage: Option<u32>,
384386
doc_stage: Option<u32>,
385387
build_stage: Option<u32>,
@@ -679,6 +681,7 @@ impl Config {
679681
set(&mut config.configure_args, build.configure_args);
680682
set(&mut config.local_rebuild, build.local_rebuild);
681683
set(&mut config.print_step_timings, build.print_step_timings);
684+
set(&mut config.print_step_rusage, build.print_step_rusage);
682685

683686
// See https://github.com/rust-lang/compiler-team/issues/326
684687
config.stage = match config.cmd {

0 commit comments

Comments
 (0)