use crossbeam_deque::{Injector, Steal, Stealer, Worker};
use crate::thread_pool::PoolJob;
pub(crate) fn steal_one<S>(source: &S) -> Option<PoolJob>
where
S: QueueStealSource,
{
loop {
match source.steal_one() {
Steal::Success(job) => return Some(job),
Steal::Empty => return None,
Steal::Retry => continue,
}
}
}
pub(crate) fn steal_batch_and_pop<S>(source: &S, dest: &Worker<PoolJob>) -> Option<PoolJob>
where
S: QueueStealSource,
{
loop {
match source.steal_batch_and_pop(dest) {
Steal::Success(job) => return Some(job),
Steal::Empty => return None,
Steal::Retry => continue,
}
}
}
pub(crate) trait QueueStealSource {
fn steal_one(&self) -> Steal<PoolJob>;
fn steal_batch_and_pop(&self, dest: &Worker<PoolJob>) -> Steal<PoolJob>;
}
impl QueueStealSource for Injector<PoolJob> {
#[inline]
fn steal_one(&self) -> Steal<PoolJob> {
self.steal()
}
#[inline]
fn steal_batch_and_pop(&self, dest: &Worker<PoolJob>) -> Steal<PoolJob> {
Injector::steal_batch_and_pop(self, dest)
}
}
impl QueueStealSource for Stealer<PoolJob> {
#[inline]
fn steal_one(&self) -> Steal<PoolJob> {
self.steal()
}
#[inline]
fn steal_batch_and_pop(&self, dest: &Worker<PoolJob>) -> Steal<PoolJob> {
Stealer::steal_batch_and_pop(self, dest)
}
}