Clean up jobserver integration
This commit is contained in:
parent
3750348daf
commit
03727a4f25
@ -12,7 +12,7 @@ crate-type = ["dylib"]
|
||||
[dependencies]
|
||||
ena = "0.13"
|
||||
log = "0.4"
|
||||
jobserver_crate = { version = "0.1", package = "jobserver" }
|
||||
jobserver_crate = { version = "0.1.13", package = "jobserver" }
|
||||
lazy_static = "1"
|
||||
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
|
||||
serialize = { path = "../libserialize" }
|
||||
|
@ -1,89 +1,5 @@
|
||||
use jobserver_crate::{Client, HelperThread, Acquired};
|
||||
use jobserver_crate::Client;
|
||||
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! {
|
||||
// We can only call `from_env` once per process
|
||||
@ -105,20 +21,12 @@ lazy_static! {
|
||||
// per-process.
|
||||
static ref GLOBAL_CLIENT: Client = unsafe {
|
||||
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 {
|
||||
@ -126,31 +34,9 @@ pub fn client() -> Client {
|
||||
}
|
||||
|
||||
pub fn acquire_thread() {
|
||||
GLOBAL_PROXY.acquire_token();
|
||||
GLOBAL_CLIENT.acquire_raw().ok();
|
||||
}
|
||||
|
||||
pub fn release_thread() {
|
||||
GLOBAL_PROXY.release_token();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
GLOBAL_CLIENT.release_raw().ok();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user