zero-pool 0.8.3

High-performance thread pool with consistent low-latency task dispatch
Documentation
use crate::queue::{EPOCH_MASK, EPOCH_MASK_HALF, Queue};
use crate::task_batch::TaskBatch;
use std::sync::atomic::Ordering;

pub struct RetiredList {
    head: *mut TaskBatch,
    tail: *mut TaskBatch,
    tick: u8,
}

impl RetiredList {
    pub fn new() -> Self {
        RetiredList {
            head: std::ptr::null_mut(),
            tail: std::ptr::null_mut(),
            tick: 0,
        }
    }

    pub fn push(&mut self, batch: *mut TaskBatch, epoch: usize) {
        unsafe {
            (*batch).retired_epoch.store(epoch, Ordering::Relaxed);

            if self.head.is_null() {
                self.head = batch;
            } else {
                (*self.tail).retired_next.store(batch, Ordering::Relaxed);
            }
            self.tail = batch;
        }
    }

    pub fn try_clean(&mut self, queue: &Queue) {
        self.tick = self.tick.wrapping_add(1);
        if self.tick == 0 {
            self.clean(queue);
        }
    }

    #[cold]
    #[inline(never)]
    fn clean(&mut self, queue: &Queue) {
        let safe_epoch = queue.advance_and_min_epoch();
        let mut current = self.head;

        // list is chronologically sorted; reclaim prefix only
        while !current.is_null() {
            let node_epoch = unsafe { (*current).retired_epoch.load(Ordering::Relaxed) };
            if safe_epoch.wrapping_sub(node_epoch).wrapping_sub(1) & EPOCH_MASK
                < (EPOCH_MASK_HALF - 1)
            {
                let batch = unsafe { Box::from_raw(current) };
                current = batch.retired_next.load(Ordering::Relaxed);
            } else {
                break;
            }
        }

        self.head = current;
        if current.is_null() {
            self.tail = std::ptr::null_mut();
        }
    }
}

impl Drop for RetiredList {
    fn drop(&mut self) {
        let mut current = self.head;
        while !current.is_null() {
            let batch = unsafe { Box::from_raw(current) };
            current = batch.retired_next.load(Ordering::Relaxed);
        }
    }
}