use std::cell::Cell;
use std::rc::Rc;
use nexus_async_rt::{Runtime, spawn_slab};
use nexus_rt::WorldBuilder;
#[test]
fn slab_spawn_and_free() {
let slab = unsafe { nexus_slab::byte::unbounded::Slab::<256>::with_chunk_capacity(16) };
let wb = WorldBuilder::new();
let mut world = wb.build();
let mut rt = Runtime::builder(&mut world).slab_unbounded(slab).build();
let done = Rc::new(Cell::new(0u32));
let d = done.clone();
rt.block_on(async move {
for i in 0..10u64 {
let d = d.clone();
drop(spawn_slab(async move {
let _ = i * 2;
d.set(d.get() + 1);
}));
}
nexus_async_rt::yield_now().await;
});
assert_eq!(done.get(), 10);
}
#[test]
fn slab_spawn_with_drop_tracker() {
let count = Rc::new(Cell::new(0u32));
let slab = unsafe { nexus_slab::byte::unbounded::Slab::<256>::with_chunk_capacity(8) };
let wb = WorldBuilder::new();
let mut world = wb.build();
let mut rt = Runtime::builder(&mut world).slab_unbounded(slab).build();
struct DropCounter(Rc<Cell<u32>>);
impl Drop for DropCounter {
fn drop(&mut self) {
self.0.set(self.0.get() + 1);
}
}
let cnt = count.clone();
rt.block_on(async move {
for _ in 0..5 {
let c = DropCounter(cnt.clone());
drop(spawn_slab(async move {
let _keep = c;
}));
}
nexus_async_rt::yield_now().await;
});
assert_eq!(count.get(), 5, "5 slab tasks = 5 drops");
}
#[test]
fn slab_claim_and_spawn() {
let slab = unsafe { nexus_slab::byte::unbounded::Slab::<256>::with_chunk_capacity(8) };
let wb = WorldBuilder::new();
let mut world = wb.build();
let mut rt = Runtime::builder(&mut world).slab_unbounded(slab).build();
let done = Rc::new(Cell::new(false));
let d = done.clone();
rt.block_on(async move {
let claim = nexus_async_rt::claim_slab();
let handle = claim.spawn(async move {
d.set(true);
});
drop(handle); nexus_async_rt::yield_now().await;
});
assert!(done.get());
}
#[test]
fn slab_bounded_reuse_after_free() {
let slab = unsafe { nexus_slab::byte::bounded::Slab::<256>::with_capacity(4) };
let wb = WorldBuilder::new();
let mut world = wb.build();
let mut rt = Runtime::builder(&mut world).slab_bounded(slab).build();
let done = Rc::new(Cell::new(0u32));
let d = done.clone();
rt.block_on(async move {
for i in 0..4u64 {
let d = d.clone();
drop(spawn_slab(async move {
let _ = i;
d.set(d.get() + 1);
}));
}
nexus_async_rt::yield_now().await;
for i in 0..4u64 {
let d = d.clone();
drop(spawn_slab(async move {
let _ = i + 100;
d.set(d.get() + 1);
}));
}
nexus_async_rt::yield_now().await;
});
assert_eq!(done.get(), 8);
}