From f07fbb2f025bbd2578346e9da1ad31b41c7ac076 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 15 Jan 2020 20:07:17 -0500 Subject: [PATCH] Split out work spawning --- src/cargo/core/compiler/job_queue.rs | 52 ++++++++++++++++++---------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/cargo/core/compiler/job_queue.rs b/src/cargo/core/compiler/job_queue.rs index cf71e6667..a79cede9c 100644 --- a/src/cargo/core/compiler/job_queue.rs +++ b/src/cargo/core/compiler/job_queue.rs @@ -347,6 +347,39 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { self.drain_the_queue(cx, plan, &helper) } + fn spawn_work_if_possible( + &mut self, + cx: &mut Context<'a, '_>, + jobserver_helper: &HelperThread, + has_errored: bool, + ) -> CargoResult<()> { + // Dequeue as much work as we can, learning about everything + // possible that can run. Note that this is also the point where we + // start requesting job tokens. Each job after the first needs to + // request a token. + while let Some((unit, job)) = self.queue.dequeue() { + self.pending_queue.push((unit, job)); + if self.active.len() + self.pending_queue.len() > 1 { + jobserver_helper.request_token(); + } + } + + // Do not actually spawn the new work if we've errored out + if has_errored { + return Ok(()); + } + + // Now that we've learned of all possible work that we can execute + // try to spawn it so long as we've got a jobserver token which says + // we're able to perform some parallel work. + while self.active.len() < self.tokens.len() + 1 && !self.pending_queue.is_empty() { + let (unit, job) = self.pending_queue.remove(0); + self.run(&unit, job, cx)?; + } + + Ok(()) + } + fn drain_the_queue( &mut self, cx: &mut Context<'a, '_>, @@ -369,24 +402,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> { let total = self.queue.len(); let mut finished = 0; loop { - // Dequeue as much work as we can, learning about everything - // possible that can run. Note that this is also the point where we - // start requesting job tokens. Each job after the first needs to - // request a token. - while let Some((unit, job)) = self.queue.dequeue() { - self.pending_queue.push((unit, job)); - if self.active.len() + self.pending_queue.len() > 1 { - jobserver_helper.request_token(); - } - } - - // Now that we've learned of all possible work that we can execute - // try to spawn it so long as we've got a jobserver token which says - // we're able to perform some parallel work. - while error.is_none() && self.active.len() < self.tokens.len() + 1 && !self.pending_queue.is_empty() { - let (unit, job) = self.pending_queue.remove(0); - self.run(&unit, job, cx)?; - } + self.spawn_work_if_possible(cx, jobserver_helper, error.is_some())?; info!( "tokens: {}, rustc_tokens: {}, waiting_rustcs: {}",