use crossbeam_queue::SegQueue;
use crate::allocators::slab::LocalPools;
struct DeferredFree {
ptr: *mut u8,
size: usize,
}
unsafe impl Send for DeferredFree {}
pub struct DeferredFreeQueue {
queue: SegQueue<DeferredFree>,
}
impl DeferredFreeQueue {
pub fn new() -> Self {
Self {
queue: SegQueue::new(),
}
}
pub fn push(&self, ptr: *mut u8, size: usize) {
self.queue.push(DeferredFree { ptr, size });
}
pub fn drain(&self, pools: &mut LocalPools) {
while let Some(deferred) = self.queue.pop() {
pools.drain_deferred(deferred.ptr, deferred.size);
}
}
pub fn is_empty(&self) -> bool {
self.queue.is_empty()
}
pub fn len(&self) -> usize {
self.queue.len()
}
}
impl Default for DeferredFreeQueue {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deferred_queue() {
let queue = DeferredFreeQueue::new();
assert!(queue.is_empty());
let ptr = Box::into_raw(Box::new(42u32)) as *mut u8;
queue.push(ptr, 4);
assert!(!queue.is_empty());
assert_eq!(queue.len(), 1);
while let Some(deferred) = queue.queue.pop() {
unsafe {
let _ = Box::from_raw(deferred.ptr as *mut u32);
}
}
}
}