use libconfig;
use num_cpus;
use std::sync::Mutex;
struct ThreadIdManager {
thread_counter: usize,
thread_limit: usize,
free_list: Vec<usize>,
}
impl ThreadIdManager {
fn new() -> ThreadIdManager {
info!("Max thread count: {}", get_max_thread_count());
info!("Preferred thread count: {}", get_preferred_thread_count());
ThreadIdManager {
thread_counter: 0,
thread_limit: get_max_thread_count(),
free_list: Vec::new(),
}
}
fn alloc(&mut self) -> usize {
if let Some(id) = self.free_list.pop() {
id
} else {
let id = self.thread_counter;
self.thread_counter += 1;
assert!(
self.thread_counter <= self.thread_limit,
"The running threads exceeds maximum allowed: {}",
self.thread_limit
);
id
}
}
fn dealloc(&mut self, id: usize) {
self.free_list.push(id);
}
}
lazy_static! {
static ref THREAD_ID_MANAGER: Mutex<ThreadIdManager> = Mutex::new(ThreadIdManager::new());
}
struct ThreadId(usize);
impl ThreadId {
fn new() -> ThreadId {
let id = THREAD_ID_MANAGER.lock().unwrap().alloc();
ThreadId(id)
}
}
impl Drop for ThreadId {
fn drop(&mut self) {
THREAD_ID_MANAGER.lock().unwrap().dealloc(self.0);
}
}
thread_local!(static THREAD_ID: ThreadId = ThreadId::new());
pub fn get_max_thread_count() -> usize {
if libconfig::MAX_THREAD_COUNT != 0 {
libconfig::MAX_THREAD_COUNT
} else {
2 * num_cpus::get()
}
}
pub fn get_preferred_thread_count() -> usize {
if libconfig::PREFERRED_THREAD_COUNT != 0 {
libconfig::PREFERRED_THREAD_COUNT
} else {
num_cpus::get()
}
}
pub fn get() -> usize {
THREAD_ID.with(|id| id.0)
}