use crate::cap::object::ObjectTag; 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 (id, generation) = crate::tests::helpers::alloc_endpoint(&mut pool).expect("pool allocate failed"); let _phys = pool.read_as::(id, generation).expect("pool get failed"); assert!( pool.get_tag(id, generation) == Ok(ObjectTag::Endpoint), "expected Endpoint tag" ); match pool.dec_ref_phys(id, generation) { Some((phys, _)) => crate::cap::kernel_objects::free_slot(phys), None => {} } } ); crate::kernel_test!( fn dec_ref_frees_slot() { let mut pool = POOL.lock(); let (id, generation) = crate::tests::helpers::alloc_endpoint(&mut pool).expect("pool allocate"); match pool.dec_ref_phys(id, generation) { Some((phys, _)) => crate::cap::kernel_objects::free_slot(phys), None => {} } let result = pool.read_as::(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 (id, generation) = crate::tests::helpers::alloc_endpoint(&mut pool).expect("pool allocate"); pool.inc_ref(id, generation).expect("inc_ref failed"); let freed = pool.dec_ref_phys(id, generation); assert!( freed.is_none(), "object freed too early (refcount should be 1)" ); let obj = pool.read_as::(id, generation); assert!(obj.is_ok(), "object should still be alive at refcount 1"); match pool.dec_ref_phys(id, generation) { Some((phys, _)) => crate::cap::kernel_objects::free_slot(phys), None => {} } } ); 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::ObjPhys, Generation), 1024>::new(); let mut count: usize = 0; loop { match crate::tests::helpers::alloc_endpoint(&mut pool) { 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)| { match pool.dec_ref_phys(id, generation) { Some((phys, _)) => crate::cap::kernel_objects::free_slot(phys), None => {} } }); } ); crate::kernel_test!( fn arena_free_already_free_is_noop() { let mut pool = POOL.lock(); let (id, generation) = crate::tests::helpers::alloc_endpoint(&mut pool).expect("alloc"); let freed = pool.free_phys(id, generation); assert!(freed.is_ok(), "first free should succeed"); assert!( pool.read_as::(id, generation).is_err(), "slot should not be accessible after free" ); } );