Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scalable jobserver for rustc #7731

Merged
merged 26 commits into from
Jan 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ec80cf9
Wire up methods for informing job queue of rustc jobserver state
Mark-Simulacrum Dec 19, 2019
4a8237f
Communicate jobserver information with each rustc
Mark-Simulacrum Dec 21, 2019
877fe69
Record the amount of rustc internal parallelism
Mark-Simulacrum Dec 21, 2019
cdcd9ad
Add documentation about the job queue and rustc
Mark-Simulacrum Dec 23, 2019
494b3c0
Gate Cargo changes behind -Zjobserver-per-rustc
Mark-Simulacrum Jan 14, 2020
f7c6d04
Introduce newtype wrapping JobId
Mark-Simulacrum Jan 15, 2020
e2f4ce1
Drop crossbeam scopes from job queue
Mark-Simulacrum Jan 15, 2020
90ef289
Move local variables to struct fields
Mark-Simulacrum Jan 16, 2020
f07fbb2
Split out work spawning
Mark-Simulacrum Jan 16, 2020
f6deb98
Split out granting rustc token requests
Mark-Simulacrum Jan 16, 2020
445de0e
Split out event handler into separate function
Mark-Simulacrum Jan 16, 2020
0d722a4
Split waiting for an event out of the primary drainer
Mark-Simulacrum Jan 16, 2020
b448d92
Do not send acquired tokens to waiting rustc threads
Mark-Simulacrum Jan 16, 2020
ae7aba2
Refactor rustc_tokens to a HashMap
Mark-Simulacrum Jan 16, 2020
c5f4690
Document ordering constraint on providing thread tokens
Mark-Simulacrum Jan 16, 2020
78afa06
Take JobQueue by-value in drain_the_queue
Mark-Simulacrum Jan 16, 2020
1d9fdee
Move transient state to separate struct
Mark-Simulacrum Jan 16, 2020
5a9af54
Add some commentary
Mark-Simulacrum Jan 16, 2020
1988dd9
Pop thread token requests from the front
Mark-Simulacrum Jan 16, 2020
50a6083
Reintroduce crossbeam threads
Mark-Simulacrum Jan 17, 2020
ec4cce9
Refactor rustc thread granting loop
Mark-Simulacrum Jan 20, 2020
4bd074e
Use an expect instead of directly panicking
Mark-Simulacrum Jan 20, 2020
25bf99b
Refactor to_send_clients to use a BTreeMap
Mark-Simulacrum Jan 20, 2020
1204a52
Elaborate on some documentation
Mark-Simulacrum Jan 20, 2020
6117f52
Stop threading Client through into the NeedsToken message
Mark-Simulacrum Jan 20, 2020
7e3e1b1
Move token truncation to just before waiting
Mark-Simulacrum Jan 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ pub struct Context<'a, 'cfg> {
/// metadata files in addition to the rlib itself. This is only filled in
/// when `pipelining` above is enabled.
rmeta_required: HashSet<Unit<'a>>,

/// When we're in jobserver-per-rustc process mode, this keeps those
/// jobserver clients for each Unit (which eventually becomes a rustc
/// process).
pub rustc_clients: HashMap<Unit<'a>, Client>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind throwing a comment on this field about what it holds?

}

impl<'a, 'cfg> Context<'a, 'cfg> {
Expand Down Expand Up @@ -112,6 +117,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
unit_dependencies,
files: None,
rmeta_required: HashSet::new(),
rustc_clients: HashMap::new(),
pipelining,
})
}
Expand Down Expand Up @@ -491,4 +497,23 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
pub fn rmeta_required(&self, unit: &Unit<'a>) -> bool {
self.rmeta_required.contains(unit) || self.bcx.config.cli_unstable().timings.is_some()
}

pub fn new_jobserver(&mut self) -> CargoResult<Client> {
let tokens = self.bcx.build_config.jobs as usize;
let client = Client::new(tokens).chain_err(|| "failed to create jobserver")?;

// Drain the client fully
for i in 0..tokens {
while let Err(e) = client.acquire_raw() {
anyhow::bail!(
"failed to fully drain {}/{} token from jobserver at startup: {:?}",
i,
tokens,
e,
);
}
Comment on lines +507 to +514
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the intent of this loop? Should it maybe be something like this?

client.acquire_raw().chain_err(|| {
    format!(
        "failed to fully drain {}/{} token from jobserver at startup",
        i, tokens
    )
})?;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I think so -- it doesn't really make any difference (bail! returns from the method anyway), but I'll send a PR cleaning it up. I suspect I had intended this as "loop until you error" but that's clearly not what this does :)

}

Ok(client)
}
}
Loading