use super::priority_queue::PriorityQueue;
use crate::lazy::Lazy;
use crate::mutex::Mutex;
struct IdAllocator {
limit: usize,
free: PriorityQueue<usize>,
}
impl IdAllocator {
fn new() -> Self {
Self {
limit: 0,
free: PriorityQueue::new(),
}
}
fn allocate(&mut self) -> usize {
self.free.pop().unwrap_or_else(|| {
let id = self.limit;
self.limit += 1;
id
})
}
fn deallocate(&mut self, id: usize) {
self.free.push(id);
}
}
static ID_ALLOCATOR: Lazy<Mutex<IdAllocator>> = Lazy::new(|| Mutex::new(IdAllocator::new()));
struct ThreadId(usize);
impl ThreadId {
fn new() -> Self {
Self(ID_ALLOCATOR.get().lock().allocate())
}
}
impl Drop for ThreadId {
fn drop(&mut self) {
ID_ALLOCATOR.get().lock().deallocate(self.0);
}
}
thread_local! {
static THREAD_ID: ThreadId = ThreadId::new();
}
pub fn get() -> usize {
THREAD_ID.with(|data| data.0)
}