use crate::cap::object::{EndpointData, ObjectData}; use crate::cap::pool::POOL; use crate::error::KernelError; use crate::types::Generation; crate::kernel_test!( fn allocate_and_get() { let mut pool = POOL.lock(); let data = ObjectData::Endpoint(EndpointData::new()); let (id, generation) = pool.allocate(data).expect("pool allocate failed"); let obj = pool.get(id, generation).expect("pool get failed"); assert!( matches!(obj, ObjectData::Endpoint(_)), "expected Endpoint variant" ); let _ = pool.dec_ref(id, generation); } ); crate::kernel_test!( fn dec_ref_frees_slot() { let mut pool = POOL.lock(); let data = ObjectData::Endpoint(EndpointData::new()); let (id, generation) = pool.allocate(data).expect("pool allocate"); let _ = pool.dec_ref(id, generation); let result = pool.get(id, generation); assert!( matches!(result, Err(KernelError::StaleGeneration)), "expected StaleGeneration after free, got {:?}", result.err() ); } ); crate::kernel_test!( fn inc_then_dec_keeps_alive() { let mut pool = POOL.lock(); let data = ObjectData::Endpoint(EndpointData::new()); let (id, generation) = pool.allocate(data).expect("pool allocate"); pool.inc_ref(id, generation).expect("inc_ref failed"); let freed = pool.dec_ref(id, generation); assert!( freed.is_none(), "object freed too early (refcount should be 1)" ); let obj = pool.get(id, generation); assert!(obj.is_ok(), "object should still be alive at refcount 1"); let _ = pool.dec_ref(id, generation); } ); crate::kernel_test!( fn exhaust_pool_returns_error() { let mut pool = POOL.lock(); let _gen0 = Generation::new(0); let mut allocated = crate::static_vec::StaticVec::<(crate::types::ObjectId, Generation), 1024>::new(); let mut count: usize = 0; loop { match pool.allocate(ObjectData::Endpoint(EndpointData::new())) { Ok((id, generation)) => { let _ = allocated.push((id, generation)); count += 1; } Err(KernelError::PoolExhausted) => break, Err(e) => panic!("unexpected error: {:?}", e), } } assert!(count > 0, "could not allocate any objects"); allocated.as_slice().iter().for_each(|&(id, generation)| { let _ = pool.dec_ref(id, generation); }); } ); crate::kernel_test!( fn arena_free_already_free_is_noop() { let mut pool = POOL.lock(); let (id, generation) = pool .allocate(ObjectData::Endpoint(EndpointData::new())) .expect("alloc"); let freed = pool.free(id, generation); assert!(freed.is_ok(), "first free should succeed"); assert!( pool.get(id, generation).is_err(), "slot should not be accessible after free" ); } );