Clean up jobserver integration
This commit is contained in:
parent
3750348daf
commit
03727a4f25
2 changed files with 8 additions and 122 deletions
|
@ -12,7 +12,7 @@ crate-type = ["dylib"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ena = "0.13"
|
ena = "0.13"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
jobserver_crate = { version = "0.1", package = "jobserver" }
|
jobserver_crate = { version = "0.1.13", package = "jobserver" }
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
|
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
|
||||||
serialize = { path = "../libserialize" }
|
serialize = { path = "../libserialize" }
|
||||||
|
|
|
@ -1,89 +1,5 @@
|
||||||
use jobserver_crate::{Client, HelperThread, Acquired};
|
use jobserver_crate::Client;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::sync::{Condvar, Arc, Mutex};
|
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct LockedProxyData {
|
|
||||||
/// The number of free thread tokens, this may include the implicit token given to the process
|
|
||||||
free: usize,
|
|
||||||
|
|
||||||
/// The number of threads waiting for a token
|
|
||||||
waiters: usize,
|
|
||||||
|
|
||||||
/// The number of tokens we requested from the server
|
|
||||||
requested: usize,
|
|
||||||
|
|
||||||
/// Stored tokens which will be dropped when we no longer need them
|
|
||||||
tokens: Vec<Acquired>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LockedProxyData {
|
|
||||||
fn request_token(&mut self, thread: &Mutex<HelperThread>) {
|
|
||||||
self.requested += 1;
|
|
||||||
thread.lock().unwrap().request_token();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn release_token(&mut self, cond_var: &Condvar) {
|
|
||||||
if self.waiters > 0 {
|
|
||||||
self.free += 1;
|
|
||||||
cond_var.notify_one();
|
|
||||||
} else {
|
|
||||||
if self.tokens.is_empty() {
|
|
||||||
// We are returning the implicit token
|
|
||||||
self.free += 1;
|
|
||||||
} else {
|
|
||||||
// Return a real token to the server
|
|
||||||
self.tokens.pop().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_token(&mut self, thread: &Mutex<HelperThread>) -> bool {
|
|
||||||
if self.free > 0 {
|
|
||||||
self.free -= 1;
|
|
||||||
self.waiters -= 1;
|
|
||||||
|
|
||||||
// We stole some token reqested by someone else
|
|
||||||
// Request another one
|
|
||||||
if self.requested + self.free < self.waiters {
|
|
||||||
self.request_token(thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_requested_token(&mut self, token: Acquired, cond_var: &Condvar) {
|
|
||||||
self.requested -= 1;
|
|
||||||
|
|
||||||
// Does anything need this token?
|
|
||||||
if self.waiters > 0 {
|
|
||||||
self.free += 1;
|
|
||||||
self.tokens.push(token);
|
|
||||||
cond_var.notify_one();
|
|
||||||
} else {
|
|
||||||
// Otherwise we'll just drop it
|
|
||||||
mem::drop(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct ProxyData {
|
|
||||||
lock: Mutex<LockedProxyData>,
|
|
||||||
cond_var: Condvar,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A helper type which makes managing jobserver tokens easier.
|
|
||||||
/// It also allows you to treat the implicit token given to the process
|
|
||||||
/// in the same manner as requested tokens.
|
|
||||||
struct Proxy {
|
|
||||||
thread: Mutex<HelperThread>,
|
|
||||||
data: Arc<ProxyData>,
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
// We can only call `from_env` once per process
|
// We can only call `from_env` once per process
|
||||||
|
@ -105,20 +21,12 @@ lazy_static! {
|
||||||
// per-process.
|
// per-process.
|
||||||
static ref GLOBAL_CLIENT: Client = unsafe {
|
static ref GLOBAL_CLIENT: Client = unsafe {
|
||||||
Client::from_env().unwrap_or_else(|| {
|
Client::from_env().unwrap_or_else(|| {
|
||||||
Client::new(32).expect("failed to create jobserver")
|
let client = Client::new(32).expect("failed to create jobserver");
|
||||||
|
// Acquire a token for the main thread which we can release later
|
||||||
|
client.acquire_raw().ok();
|
||||||
|
client
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
static ref GLOBAL_PROXY: Proxy = {
|
|
||||||
let data = Arc::new(ProxyData::default());
|
|
||||||
|
|
||||||
Proxy {
|
|
||||||
data: data.clone(),
|
|
||||||
thread: Mutex::new(client().into_helper_thread(move |token| {
|
|
||||||
data.lock.lock().unwrap().new_requested_token(token.unwrap(), &data.cond_var);
|
|
||||||
}).unwrap()),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client() -> Client {
|
pub fn client() -> Client {
|
||||||
|
@ -126,31 +34,9 @@ pub fn client() -> Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn acquire_thread() {
|
pub fn acquire_thread() {
|
||||||
GLOBAL_PROXY.acquire_token();
|
GLOBAL_CLIENT.acquire_raw().ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn release_thread() {
|
pub fn release_thread() {
|
||||||
GLOBAL_PROXY.release_token();
|
GLOBAL_CLIENT.release_raw().ok();
|
||||||
}
|
|
||||||
|
|
||||||
impl Proxy {
|
|
||||||
fn release_token(&self) {
|
|
||||||
self.data.lock.lock().unwrap().release_token(&self.data.cond_var);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn acquire_token(&self) {
|
|
||||||
let mut data = self.data.lock.lock().unwrap();
|
|
||||||
data.waiters += 1;
|
|
||||||
if data.take_token(&self.thread) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Request a token for us
|
|
||||||
data.request_token(&self.thread);
|
|
||||||
loop {
|
|
||||||
data = self.data.cond_var.wait(data).unwrap();
|
|
||||||
if data.take_token(&self.thread) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue