use std::alloc::{GlobalAlloc, Layout};
use std::hint::black_box;
use std::sync::atomic::{AtomicBool, Ordering};
use stoolap_jemalloc::Jemalloc;
struct Reclaiming;
const INNER: Jemalloc = Jemalloc::new();
static RECLAIM: AtomicBool = AtomicBool::new(false);
#[global_allocator]
static GLOBAL: Reclaiming = Reclaiming;
unsafe impl GlobalAlloc for Reclaiming {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
unsafe { INNER.alloc(layout) }
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe { INNER.dealloc(ptr, layout) };
if RECLAIM.load(Ordering::Relaxed) {
if layout.size() > 1 << 20 {
unsafe {
let again = INNER.alloc_zeroed(layout);
assert!(!again.is_null());
INNER.dealloc(again, layout);
}
} else {
stoolap_jemalloc::purge();
}
}
}
}
#[test]
fn reclaim_right_after_free() {
for _ in 0..3 {
let small = black_box(Box::new([7u64; 4]));
let tiny = black_box(Box::new(1u8));
let huge = black_box(vec![3u8; (1 << 20) + 4096].into_boxed_slice());
RECLAIM.store(true, Ordering::Relaxed);
drop(small);
drop(tiny);
drop(huge);
RECLAIM.store(false, Ordering::Relaxed);
}
}