Skip to content

Commit a0be578

Browse files
committed
Auto merge of #7344 - alexcrichton:jobserver, r=ehuss
Create a jobserver with N tokens, not N-1 I recently added `jobserver` support to the `cc` crate and ended up running afoul of a `jobserver` quirk on Windows. Due to how it's implemented, on Windows you can't actually add more than the intial number of tokens to the jobserver (it uses an IPC semaphore). On Unix, however, you can since you're just writing bytes into a pipe. In `cc`, however, I found it convenient to control parallelism by simply releasing a token before the parallel loop, then reacquiring the token after the loop. That way the loop just has to acquire a token for each job it wants to spawn and then release it when the job finishes. This is a bit simpler than trying to juggle the "implicit token" all over the place as well as coordinating its use. It's technically invalid because it allows a brief moment of `N+1` parallelism since we release a token and then do a bit of work to acquire a new token, but that's hopefully not really the end of the world. In any case this commit updates Cargo's creation of a jobserver to create it with `N` tokens instead of `N-1`. The same semantics are preserved where Cargo then immediately acquires one of the tokens, but the difference is that this "implicit token" can be released back to the jobserver pool, unlike before.
2 parents 651b1c5 + cab8640 commit a0be578

File tree

1 file changed

+8
-4
lines changed
  • src/cargo/core/compiler/context

1 file changed

+8
-4
lines changed

src/cargo/core/compiler/context/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,16 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
8585
// all share the same jobserver.
8686
//
8787
// Note that if we don't have a jobserver in our environment then we
88-
// create our own, and we create it with `n-1` tokens because one token
89-
// is ourself, a running process.
88+
// create our own, and we create it with `n` tokens, but immediately
89+
// acquire one, because one token is ourself, a running process.
9090
let jobserver = match config.jobserver_from_env() {
9191
Some(c) => c.clone(),
92-
None => Client::new(bcx.build_config.jobs as usize - 1)
93-
.chain_err(|| "failed to create jobserver")?,
92+
None => {
93+
let client = Client::new(bcx.build_config.jobs as usize)
94+
.chain_err(|| "failed to create jobserver")?;
95+
client.acquire_raw()?;
96+
client
97+
}
9498
};
9599

96100
let pipelining = bcx

0 commit comments

Comments
 (0)