+
+#[cfg(not(unix))]
+/// getrusage is not available on non-unix platforms. So for now, we do not
+/// bother trying to make a shim for it.
+fn format_rusage_data() -> Option<String> {
+ None
+}
+
+#[cfg(unix)]
+/// Tries to build a string with human readable data for several of the rusage
+/// fields. Note that we are focusing mainly on data that we believe to be
+/// supplied on Linux (the `rusage` struct has other fields in it but they are
+/// currently unsupported by Linux).
+fn format_rusage_data() -> Option<String> {
+ let rusage: libc::rusage = unsafe {
+ let mut recv = std::mem::zeroed();
+ // -1 is RUSAGE_CHILDREN, which means to get the rusage for all children
+ // (and grandchildren, etc) processes that have respectively terminated
+ // and been waited for.
+ let retval = libc::getrusage(-1, &mut recv);
+ if retval != 0 {
+ return None;
+ }
+ recv
+ };
+ // Mac OS X reports the maxrss in bytes, not kb.
+ let divisor = if env::consts::OS == "macos" { 1024 } else { 1 };
+ let maxrss = rusage.ru_maxrss + (divisor - 1) / divisor;
+
+ let mut init_str = format!(
+ "user: {USER_SEC}.{USER_USEC:03} \
+ sys: {SYS_SEC}.{SYS_USEC:03} \
+ max rss (kb): {MAXRSS}",
+ USER_SEC = rusage.ru_utime.tv_sec,
+ USER_USEC = rusage.ru_utime.tv_usec,
+ SYS_SEC = rusage.ru_stime.tv_sec,
+ SYS_USEC = rusage.ru_stime.tv_usec,
+ MAXRSS = maxrss
+ );
+
+ // The remaining rusage stats vary in platform support. So we treat
+ // uniformly zero values in each category as "not worth printing", since it
+ // either means no events of that type occurred, or that the platform
+ // does not support it.
+
+ let minflt = rusage.ru_minflt;
+ let majflt = rusage.ru_majflt;
+ if minflt != 0 || majflt != 0 {
+ init_str.push_str(&format!(" page reclaims: {} page faults: {}", minflt, majflt));
+ }
+
+ let inblock = rusage.ru_inblock;
+ let oublock = rusage.ru_oublock;
+ if inblock != 0 || oublock != 0 {
+ init_str.push_str(&format!(" fs block inputs: {} fs block outputs: {}", inblock, oublock));
+ }
+
+ let nvcsw = rusage.ru_nvcsw;
+ let nivcsw = rusage.ru_nivcsw;
+ if nvcsw != 0 || nivcsw != 0 {
+ init_str.push_str(&format!(
+ " voluntary ctxt switches: {} involuntary ctxt switches: {}",
+ nvcsw, nivcsw
+ ));
+ }
+
+ return Some(init_str);
+}