Skip to content

Commit c4797fa

Browse files
committedJun 12, 2019
Auto merge of #61758 - Centril:rollup-ew2uxng, r=Centril
Rollup of 9 pull requests Successful merges: - #60187 (Generator optimization: Overlap locals that never have storage live at the same time) - #61348 (Implement Clone::clone_from for Option and Result) - #61568 (Use Symbol, Span in libfmt_macros) - #61632 (ci: Collect CPU usage statistics on Azure) - #61654 (use pattern matching for slices destructuring) - #61671 (implement nth_back for Range(Inclusive)) - #61688 (is_fp and is_floating_point do the same thing, remove the former) - #61705 (Pass cflags rather than cxxflags to LLVM as CMAKE_C_FLAGS) - #61734 (Migrate rust-by-example to MdBook2) Failed merges: r? @ghost
2 parents 05083c2 + 4748b5b commit c4797fa

File tree

30 files changed

+579
-234
lines changed

30 files changed

+579
-234
lines changed
 

‎.azure-pipelines/steps/run.yml

+16
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ steps:
1111
- checkout: self
1212
fetchDepth: 2
1313

14+
# Spawn a background process to collect CPU usage statistics which we'll upload
15+
# at the end of the build. See the comments in the script here for more
16+
# information.
17+
- bash: python src/ci/cpu-usage-over-time.py &> cpu-usage.csv &
18+
displayName: "Collect CPU-usage statistics in the background"
19+
1420
- bash: printenv | sort
1521
displayName: Show environment variables
1622

@@ -142,3 +148,13 @@ steps:
142148
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
143149
condition: and(succeeded(), or(eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1')))
144150
displayName: Upload artifacts
151+
152+
# Upload CPU usage statistics that we've been gathering this whole time. Always
153+
# execute this step in case we want to inspect failed builds, but don't let
154+
# errors here ever fail the build since this is just informational.
155+
- bash: aws s3 cp --acl public-read cpu-usage.csv s3://$DEPLOY_BUCKET/rustc-builds/$BUILD_SOURCEVERSION/cpu-$SYSTEM_JOBNAME.csv
156+
env:
157+
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
158+
condition: contains(variables, 'AWS_SECRET_ACCESS_KEY')
159+
continueOnError: true
160+
displayName: Upload CPU usage statistics

‎Cargo.lock

+3
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,9 @@ dependencies = [
910910
[[package]]
911911
name = "fmt_macros"
912912
version = "0.0.0"
913+
dependencies = [
914+
"syntax_pos 0.0.0",
915+
]
913916

914917
[[package]]
915918
name = "fnv"

‎src/bootstrap/doc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ book!(
6464
EmbeddedBook, "src/doc/embedded-book", "embedded-book", RustbookVersion::MdBook2;
6565
Nomicon, "src/doc/nomicon", "nomicon", RustbookVersion::MdBook2;
6666
Reference, "src/doc/reference", "reference", RustbookVersion::MdBook1;
67-
RustByExample, "src/doc/rust-by-example", "rust-by-example", RustbookVersion::MdBook1;
67+
RustByExample, "src/doc/rust-by-example", "rust-by-example", RustbookVersion::MdBook2;
6868
RustcBook, "src/doc/rustc", "rustc", RustbookVersion::MdBook1;
6969
RustdocBook, "src/doc/rustdoc", "rustdoc", RustbookVersion::MdBook2;
7070
);

‎src/bootstrap/native.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ fn configure_cmake(builder: &Builder<'_>,
416416

417417
cfg.build_arg("-j").build_arg(builder.jobs().to_string());
418418
let mut cflags = builder.cflags(target, GitRepo::Llvm).join(" ");
419-
if let Some(ref s) = builder.config.llvm_cxxflags {
419+
if let Some(ref s) = builder.config.llvm_cflags {
420420
cflags.push_str(&format!(" {}", s));
421421
}
422422
cfg.define("CMAKE_C_FLAGS", cflags);

‎src/ci/cpu-usage-over-time.py

+175
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#!/usr/bin/env python
2+
# ignore-tidy-linelength
3+
4+
# This is a small script that we use on CI to collect CPU usage statistics of
5+
# our builders. By seeing graphs of CPU usage over time we hope to correlate
6+
# that with possible improvements to Rust's own build system, ideally diagnosing
7+
# that either builders are always fully using their CPU resources or they're
8+
# idle for long stretches of time.
9+
#
10+
# This script is relatively simple, but it's platform specific. Each platform
11+
# (OSX/Windows/Linux) has a different way of calculating the current state of
12+
# CPU at a point in time. We then compare two captured states to determine the
13+
# percentage of time spent in one state versus another. The state capturing is
14+
# all platform-specific but the loop at the bottom is the cross platform part
15+
# that executes everywhere.
16+
#
17+
# # Viewing statistics
18+
#
19+
# All builders will upload their CPU statistics as CSV files to our S3 buckets.
20+
# These URLS look like:
21+
#
22+
# https://$bucket.s3.amazonaws.com/rustc-builds/$commit/cpu-$builder.csv
23+
#
24+
# for example
25+
#
26+
# https://rust-lang-ci2.s3.amazonaws.com/rustc-builds/68baada19cd5340f05f0db15a3e16d6671609bcc/cpu-x86_64-apple.csv
27+
#
28+
# Each CSV file has two columns. The first is the timestamp of the measurement
29+
# and the second column is the % of idle cpu time in that time slice. Ideally
30+
# the second column is always zero.
31+
#
32+
# Once you've downloaded a file there's various ways to plot it and visualize
33+
# it. For command line usage you can use a script like so:
34+
#
35+
# set timefmt '%Y-%m-%dT%H:%M:%S'
36+
# set xdata time
37+
# set ylabel "Idle CPU %"
38+
# set xlabel "Time"
39+
# set datafile sep ','
40+
# set term png
41+
# set output "printme.png"
42+
# set grid
43+
# builder = "i686-apple"
44+
# plot "cpu-".builder.".csv" using 1:2 with lines title builder
45+
#
46+
# Executed as `gnuplot < ./foo.plot` it will generate a graph called
47+
# `printme.png` which you can then open up. If you know how to improve this
48+
# script or the viewing process that would be much appreciated :) (or even if
49+
# you know how to automate it!)
50+
51+
import datetime
52+
import sys
53+
import time
54+
55+
if sys.platform == 'linux2':
56+
class State:
57+
def __init__(self):
58+
with open('/proc/stat', 'r') as file:
59+
data = file.readline().split()
60+
if data[0] != 'cpu':
61+
raise Exception('did not start with "cpu"')
62+
self.user = int(data[1])
63+
self.nice = int(data[2])
64+
self.system = int(data[3])
65+
self.idle = int(data[4])
66+
self.iowait = int(data[5])
67+
self.irq = int(data[6])
68+
self.softirq = int(data[7])
69+
self.steal = int(data[8])
70+
self.guest = int(data[9])
71+
self.guest_nice = int(data[10])
72+
73+
def idle_since(self, prev):
74+
user = self.user - prev.user
75+
nice = self.nice - prev.nice
76+
system = self.system - prev.system
77+
idle = self.idle - prev.idle
78+
iowait = self.iowait - prev.iowait
79+
irq = self.irq - prev.irq
80+
softirq = self.softirq - prev.softirq
81+
steal = self.steal - prev.steal
82+
guest = self.guest - prev.guest
83+
guest_nice = self.guest_nice - prev.guest_nice
84+
total = user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice
85+
return float(idle) / float(total) * 100
86+
87+
elif sys.platform == 'win32':
88+
from ctypes.wintypes import DWORD
89+
from ctypes import Structure, windll, WinError, GetLastError, byref
90+
91+
class FILETIME(Structure):
92+
_fields_ = [
93+
("dwLowDateTime", DWORD),
94+
("dwHighDateTime", DWORD),
95+
]
96+
97+
class State:
98+
def __init__(self):
99+
idle, kernel, user = FILETIME(), FILETIME(), FILETIME()
100+
101+
success = windll.kernel32.GetSystemTimes(
102+
byref(idle),
103+
byref(kernel),
104+
byref(user),
105+
)
106+
107+
assert success, WinError(GetLastError())[1]
108+
109+
self.idle = (idle.dwHighDateTime << 32) | idle.dwLowDateTime
110+
self.kernel = (kernel.dwHighDateTime << 32) | kernel.dwLowDateTime
111+
self.user = (user.dwHighDateTime << 32) | user.dwLowDateTime
112+
113+
def idle_since(self, prev):
114+
idle = self.idle - prev.idle
115+
user = self.user - prev.user
116+
kernel = self.kernel - prev.kernel
117+
return float(idle) / float(user + kernel) * 100
118+
119+
elif sys.platform == 'darwin':
120+
from ctypes import *
121+
libc = cdll.LoadLibrary('/usr/lib/libc.dylib')
122+
123+
PROESSOR_CPU_LOAD_INFO = c_int(2)
124+
CPU_STATE_USER = 0
125+
CPU_STATE_SYSTEM = 1
126+
CPU_STATE_IDLE = 2
127+
CPU_STATE_NICE = 3
128+
c_int_p = POINTER(c_int)
129+
130+
class State:
131+
def __init__(self):
132+
num_cpus_u = c_uint(0)
133+
cpu_info = c_int_p()
134+
cpu_info_cnt = c_int(0)
135+
err = libc.host_processor_info(
136+
libc.mach_host_self(),
137+
PROESSOR_CPU_LOAD_INFO,
138+
byref(num_cpus_u),
139+
byref(cpu_info),
140+
byref(cpu_info_cnt),
141+
)
142+
assert err == 0
143+
self.user = 0
144+
self.system = 0
145+
self.idle = 0
146+
self.nice = 0
147+
cur = 0
148+
while cur < cpu_info_cnt.value:
149+
self.user += cpu_info[cur + CPU_STATE_USER]
150+
self.system += cpu_info[cur + CPU_STATE_SYSTEM]
151+
self.idle += cpu_info[cur + CPU_STATE_IDLE]
152+
self.nice += cpu_info[cur + CPU_STATE_NICE]
153+
cur += num_cpus_u.value
154+
155+
def idle_since(self, prev):
156+
user = self.user - prev.user
157+
system = self.system - prev.system
158+
idle = self.idle - prev.idle
159+
nice = self.nice - prev.nice
160+
return float(idle) / float(user + system + idle + nice) * 100.0
161+
162+
else:
163+
print('unknown platform', sys.platform)
164+
sys.exit(1)
165+
166+
cur_state = State();
167+
print("Time,Idle")
168+
while True:
169+
time.sleep(1);
170+
next_state = State();
171+
now = datetime.datetime.utcnow().isoformat()
172+
idle = next_state.idle_since(cur_state)
173+
print("%s,%s" % (now, idle))
174+
sys.stdout.flush()
175+
cur_state = next_state

‎src/doc/rust-by-example

Submodule rust-by-example updated 77 files

‎src/libcore/iter/range.rs

+41
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,19 @@ impl<A: Step> DoubleEndedIterator for ops::Range<A> {
281281
None
282282
}
283283
}
284+
285+
#[inline]
286+
fn nth_back(&mut self, n: usize) -> Option<A> {
287+
if let Some(minus_n) = self.end.sub_usize(n) {
288+
if minus_n > self.start {
289+
self.end = minus_n.sub_one();
290+
return Some(self.end.clone())
291+
}
292+
}
293+
294+
self.end = self.start.clone();
295+
None
296+
}
284297
}
285298

286299
#[stable(feature = "fused", since = "1.26.0")]
@@ -438,6 +451,34 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
438451
})
439452
}
440453

454+
#[inline]
455+
fn nth_back(&mut self, n: usize) -> Option<A> {
456+
self.compute_is_empty();
457+
if self.is_empty.unwrap_or_default() {
458+
return None;
459+
}
460+
461+
if let Some(minus_n) = self.end.sub_usize(n) {
462+
use crate::cmp::Ordering::*;
463+
464+
match minus_n.partial_cmp(&self.start) {
465+
Some(Greater) => {
466+
self.is_empty = Some(false);
467+
self.end = minus_n.sub_one();
468+
return Some(minus_n);
469+
}
470+
Some(Equal) => {
471+
self.is_empty = Some(true);
472+
return Some(minus_n);
473+
}
474+
_ => {}
475+
}
476+
}
477+
478+
self.is_empty = Some(true);
479+
None
480+
}
481+
441482
#[inline]
442483
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
443484
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>

‎src/libcore/option.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ use crate::pin::Pin;
145145
// which basically means it must be `Option`.
146146

147147
/// The `Option` type. See [the module level documentation](index.html) for more.
148-
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
148+
#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
149149
#[stable(feature = "rust1", since = "1.0.0")]
150150
pub enum Option<T> {
151151
/// No value
@@ -1040,6 +1040,25 @@ fn expect_failed(msg: &str) -> ! {
10401040
// Trait implementations
10411041
/////////////////////////////////////////////////////////////////////////////
10421042

1043+
#[stable(feature = "rust1", since = "1.0.0")]
1044+
impl<T: Clone> Clone for Option<T> {
1045+
#[inline]
1046+
fn clone(&self) -> Self {
1047+
match self {
1048+
Some(x) => Some(x.clone()),
1049+
None => None,
1050+
}
1051+
}
1052+
1053+
#[inline]
1054+
fn clone_from(&mut self, source: &Self) {
1055+
match (self, source) {
1056+
(Some(to), Some(from)) => to.clone_from(from),
1057+
(to, from) => *to = from.clone(),
1058+
}
1059+
}
1060+
}
1061+
10431062
#[stable(feature = "rust1", since = "1.0.0")]
10441063
impl<T> Default for Option<T> {
10451064
/// Returns [`None`][Option::None].

‎src/libcore/result.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ use crate::ops::{self, Deref};
240240
///
241241
/// [`Ok`]: enum.Result.html#variant.Ok
242242
/// [`Err`]: enum.Result.html#variant.Err
243-
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
243+
#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
244244
#[must_use = "this `Result` may be an `Err` variant, which should be handled"]
245245
#[stable(feature = "rust1", since = "1.0.0")]
246246
pub enum Result<T, E> {
@@ -1003,6 +1003,27 @@ fn unwrap_failed<E: fmt::Debug>(msg: &str, error: E) -> ! {
10031003
// Trait implementations
10041004
/////////////////////////////////////////////////////////////////////////////
10051005

1006+
#[stable(feature = "rust1", since = "1.0.0")]
1007+
impl<T: Clone, E: Clone> Clone for Result<T, E> {
1008+
#[inline]
1009+
fn clone(&self) -> Self {
1010+
match self {
1011+
Ok(x) => Ok(x.clone()),
1012+
Err(x) => Err(x.clone()),
1013+
}
1014+
}
1015+
1016+
#[inline]
1017+
fn clone_from(&mut self, source: &Self) {
1018+
match (self, source) {
1019+
(Ok(to), Ok(from)) => to.clone_from(from),
1020+
(Err(to), Err(from)) => to.clone_from(from),
1021+
(to, from) => *to = from.clone(),
1022+
}
1023+
}
1024+
}
1025+
1026+
10061027
#[stable(feature = "rust1", since = "1.0.0")]
10071028
impl<T, E> IntoIterator for Result<T, E> {
10081029
type Item = T;

0 commit comments

Comments
 (0)
Please sign in to comment.