Problem
The current jobserver implementation in Cargo is built to consume as much tokens as possible, and hold on to them for as long as there is work to do. This means that as soon as a single cargo build capable of using all the jobserver jobs is started, it can block other processes from acquiring a single token for a long time, effectively blocking them from starting.
This goes against the spirit of jobserver, which is to run jobs in an (approximate) round-robin fashion. It also penalizes concurrent builds with other tasks that cannot saturate the CPUs on their own: normally they would run n < nproc jobs in parallel with nproc - n jobs used by Cargo; however, due to Cargo's implementation, cargo will run with nproc jobs and finish first, then the remaining jobs will slowly toil with n < nproc jobs, leaving the remaining CPUs idle. This is also a major pain for interactively running separate build processes in parallel, as you can't start any other process without acquiring the first token for it, so the user needs to wait a long time for cargo to free a single token.
Steps
- Start a jobserver (e.g. steve).
- Start a
cargo build under the jobserver (e.g. via stevie cargo build).
- Try to start another job needing a jobserver token (e.g.
stevie echo 1).
Normally (i.e. with a jobserver implementation of make or ninja) the task should complete within seconds. However, when cargo is used, it won't start until cargo finishes building.
Possible Solution(s)
Acquire a single token for every job that's about to be run, and release it as soon as the job finishes. Do not hold tokens longer than necessary.
Notes
No response
Version
cargo 1.97.1 (c980f4866 2026-06-30) (gentoo)
Problem
The current jobserver implementation in Cargo is built to consume as much tokens as possible, and hold on to them for as long as there is work to do. This means that as soon as a single
cargobuild capable of using all the jobserver jobs is started, it can block other processes from acquiring a single token for a long time, effectively blocking them from starting.This goes against the spirit of jobserver, which is to run jobs in an (approximate) round-robin fashion. It also penalizes concurrent builds with other tasks that cannot saturate the CPUs on their own: normally they would run
n < nprocjobs in parallel withnproc - njobs used by Cargo; however, due to Cargo's implementation, cargo will run withnprocjobs and finish first, then the remaining jobs will slowly toil withn < nprocjobs, leaving the remaining CPUs idle. This is also a major pain for interactively running separate build processes in parallel, as you can't start any other process without acquiring the first token for it, so the user needs to wait a long time for cargo to free a single token.Steps
cargo buildunder the jobserver (e.g. viastevie cargo build).stevie echo 1).Normally (i.e. with a jobserver implementation of
makeorninja) the task should complete within seconds. However, whencargois used, it won't start until cargo finishes building.Possible Solution(s)
Acquire a single token for every job that's about to be run, and release it as soon as the job finishes. Do not hold tokens longer than necessary.
Notes
No response
Version