Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upIntegrate jobserver support to parallel codegen #42682
Conversation
rust-highfive
assigned
arielb1
Jun 15, 2017
This comment has been minimized.
This comment has been minimized.
|
r? @arielb1 (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
rust-highfive
assigned
michaelwoerister
and unassigned
arielb1
Jun 15, 2017
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
3 times, most recently
from
c765aad
to
4e8e13a
Jun 15, 2017
michaelwoerister
reviewed
Jun 16, 2017
|
Very nice! I'm excited about this Regarding the implementation, I'm not quite clear on how token handling works there. Wouldn't it be easier to just move one token into each |
| @@ -82,16 +84,11 @@ pub fn run(sess: &session::Session, | |||
| // For each of our upstream dependencies, find the corresponding rlib and | |||
| // load the bitcode from the archive. Then merge it into the current LLVM | |||
| // module that we've got. | |||
| link::each_linked_rlib(sess, &mut |cnum, path| { | |||
| // `#![no_builtins]` crates don't participate in LTO. | |||
| if sess.cstore.is_no_builtins(cnum) { | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jun 16, 2017
Author
Member
Yeah this query just ended up having a lot of dependencies on sess so I figured it'd be best to move it way up to the beginning instead of only running it back here.
| execute_work_item(&cgcx, work); | ||
| let mut tokens = Vec::new(); | ||
| let mut running = 0; | ||
| while work_items.len() > 0 || running > 0 { |
This comment has been minimized.
This comment has been minimized.
michaelwoerister
Jun 16, 2017
Contributor
Could you add a comment here saying something to the effect of "This is our 'main loop', taking care of spawning worker threads and communicating with live ones via message passing -- so we have to keep it running as long as there's still work that hasn't been doled out to a worker (work_items > 0) or if there are still live workers to be communicated with (running > 0)."
| scope, | ||
| tx.clone(), | ||
| work_items.pop().unwrap(), | ||
| work_items.len()); |
This comment has been minimized.
This comment has been minimized.
michaelwoerister
Jun 16, 2017
Contributor
I'm not very fond this: mutating work_items via pop and then taking its len. I assume that we have a defined evaluation order of function arguments, but I don't like relying on it.
| // possible. Remember that we have an ambient token available to us | ||
| // hence the `+1` here. | ||
| // | ||
| // Also note that we may actually acquire more tokens than we need, so |
This comment has been minimized.
This comment has been minimized.
michaelwoerister
Jun 16, 2017
Contributor
When does that happen? If we abort early because of an error?
| // | ||
| // Also note that we may actually acquire more tokens than we need, so | ||
| // in that case just truncate the `tokens` list every time we pass | ||
| // through here. |
This comment has been minimized.
This comment has been minimized.
michaelwoerister
Jun 16, 2017
Contributor
Could you add that truncating implies dropping and thus releasing tokens?
| work_items.len()); | ||
| running += 1; | ||
| } | ||
| tokens.truncate(running.saturating_sub(1)); |
This comment has been minimized.
This comment has been minimized.
michaelwoerister
Jun 16, 2017
Contributor
I'm not quite sure how this works. Can't this cause tokens to be lost without a spawn_work having been called for them?
|
|
||
| // Set up a destructor which will fire off a message that we're done as | ||
| // we exit. | ||
| struct Bomb { |
This comment has been minimized.
This comment has been minimized.
| if sess.cstore.is_no_builtins(cnum) { | ||
| return | ||
| } | ||
| each_linked_rlib.push((cnum, path.to_path_buf())); |
This comment has been minimized.
This comment has been minimized.
michaelwoerister
Jun 16, 2017
Contributor
If the each_linked_rlib field is LTO-specific, we should probably change to the name to reflect this.
| // Execute the work itself, and if it finishes successfully then flag | ||
| // ourselves as a success as well. | ||
| if execute_work_item(&cgcx, work).is_err() { | ||
| drop(cgcx.tx.send(Message::AbortIfErrors)); |
This comment has been minimized.
This comment has been minimized.
michaelwoerister
Jun 16, 2017
Contributor
One could argue that it would be cleaner to also mem::forget the bomb in this case.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jun 16, 2017
Author
Member
Yeah I wasn't quite sure how this should be handled, I think that if you see a FatalError then a diagnostic has already been sent off, which in turn already sent AbortIfErrors. In that sense it may be fruitless to send another message here, so I'll just ignore the result.
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| //! Scoped threads, copied from `crossbeam` |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
shepmaster
added
the
S-waiting-on-author
label
Jun 16, 2017
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
from
4e8e13a
to
b364714
Jun 16, 2017
This comment has been minimized.
This comment has been minimized.
|
Ok, updated! @michaelwoerister I added a large comment above the "main loop" which I believe should answer your questions about the token management, but if you'd like me to clarify anything please just let me know! |
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
from
b364714
to
0f66436
Jun 17, 2017
This comment has been minimized.
This comment has been minimized.
|
|
michaelwoerister
reviewed
Jun 19, 2017
| // manner we can ensure that the maximum number of parallel workers is | ||
| // capped at any one point in time. | ||
| // | ||
| // The jobserver protocol is a little unique, however. We, as a running |
This comment has been minimized.
This comment has been minimized.
michaelwoerister
Jun 19, 2017
Contributor
Because concurrent programming isn't complicated enough by itself already
This comment has been minimized.
This comment has been minimized.
|
Thanks for the clarifying comment about the jobserver protocol! r=me once the merge conflict is fixed. |
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
from
0f66436
to
5d00e5e
Jun 19, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors: r=michaelwoerister |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jun 20, 2017
This comment has been minimized.
This comment has been minimized.
|
|
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
from
5d00e5e
to
a014634
Jun 20, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors: r=michaelwoerister |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jun 20, 2017
arielb1
added
S-waiting-on-bors
and removed
S-waiting-on-author
labels
Jun 20, 2017
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
Linking failure?
|
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
from
a014634
to
2376e0d
Jun 20, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors: r=michaelwoerister |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
|
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
from
2376e0d
to
451d392
Jun 21, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors: r=michaelwoerister |
This comment has been minimized.
This comment has been minimized.
|
|
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
from
451d392
to
46dc6da
Jun 21, 2017
alexcrichton
force-pushed the
alexcrichton:jobserver
branch
from
46dc6da
to
201f069
Jun 21, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors: r=michaelwoerister |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jun 21, 2017
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@bors: retry
* osx timed out
…On Wed, Jun 21, 2017 at 4:24 PM, bors ***@***.***> wrote:
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jun 22, 2017
This comment has been minimized.
This comment has been minimized.
|
|
bors
merged commit 201f069
into
rust-lang:master
Jun 22, 2017
This was referenced Jun 22, 2017
alexcrichton
deleted the
alexcrichton:jobserver
branch
Jun 22, 2017
rillian
referenced this pull request
Jun 23, 2017
Closed
ICE compiling rustc-serialize under sccache 'failed to acquire jobserver token' #42867
This comment has been minimized.
This comment has been minimized.
|
So does this only support invoking |
This comment has been minimized.
This comment has been minimized.
|
@jdm it's a little more nuanced than that. Cargo also creates a jobserver in addition to consuming one, meaning that rustc will basically always use that jobserver now. If Cargo inherits a jobserver though then rustc likely will too. You need to tweak makefiles calling rustc/cargo though to actually let them inherit the jobserver, notably adding a For build scripts invoking make the |
alexcrichton commentedJun 15, 2017
This commit integrates the
jobservercrate into the compiler. The crate waspreviously integrated in to Cargo as part of rust-lang/cargo#4110. The purpose
here is to two-fold:
Primarily the compiler can cooperate with Cargo on parallelism. When you run
cargo build -j4then this'll make sure that the entire build process betweenCargo/rustc won't use more than 4 cores, whereas today you'd get 4 rustc
instances which may all try to spawn lots of threads.
Secondarily rustc/Cargo can now integrate with a foreign GNU
makejobserver.This means that if you call cargo/rustc from
makeor anotherjobserver-compatible implementation it'll use foreign parallelism settings
instead of creating new ones locally.
As the number of parallel codegen instances in the compiler continues to grow
over time with the advent of incremental compilation it's expected that this'll
become more of a problem, so this is intended to nip concurrent concerns in the
bud by having all the tools to cooperate!
Note that while rustc has support for itself creating a jobserver it's far more
likely that rustc will always use the jobserver configured by Cargo. Cargo today
will now set a jobserver unconditionally for rustc to use.