#[test] fn one_fault_retirement_preserves_two_healthy_processes_and_exact_inventory() { let (mut table, control) = setup(); let baseline = driver(&mut table).inventory(); let init = spawn(&mut table); driver(&mut table).activate(init); let survivor = spawn(&mut table); let doomed = spawn(&mut table); let all_live = driver(&mut table).inventory(); assert_eq!(table.snapshot().published, 3); assert_eq!(table.wait_child_outcome(doomed), Err(Error::Busy)); assert_eq!(driver(&mut table).inventory(), all_live); driver(&mut table).yield_current(); driver(&mut table).activate(doomed); let fault = Fault::from_lower_el_data_abort(0x9000_0004, 0x9000_0000).unwrap(); table.fault_current(fault).unwrap(); assert_eq!(driver(&mut table).inventory(), all_live); driver(&mut table).activate(init); assert_eq!(table.record(init).unwrap().resources.state, threads::State::Running); assert_eq!(table.record(survivor).unwrap().resources.state, threads::State::Ready); assert_eq!(table.wait_child(doomed), Err(Error::State)); assert_eq!(table.wait_child_outcome(doomed), Ok(Outcome::Fault(fault))); assert_eq!(table.snapshot().published, 2); assert_eq!(table.record(survivor).unwrap().resources.state, threads::State::Ready); driver(&mut table).yield_current(); driver(&mut table).activate(survivor); table.exit_current(42).unwrap(); driver(&mut table).activate(init); assert_eq!(table.wait_child_outcome(survivor), Ok(Outcome::Exited(42))); assert_eq!(table.snapshot().published, 1); table.exit_current(0).unwrap(); control.borrow_mut().execution.kernel_bootstrap = true; assert_eq!(table.wait_child_outcome(init), Ok(Outcome::Exited(0))); assert_eq!(table.snapshot(), Snapshot::default()); assert_eq!(driver(&mut table).inventory(), baseline); } #[test] fn early_free_of_active_pinned_page_is_rejected_without_owner_change() { let (mut table, control) = setup(); let baseline = driver(&mut table).inventory(); let process = spawn(&mut table); driver(&mut table).activate(process); let record = table.record(process).unwrap(); let page = record.resources.handles[1].unwrap(); let owner = record.resources.resource_owner; let inventory = driver(&mut table).inventory(); let snapshot = table.snapshot(); assert_eq!(driver(&mut table).frames.release(page, owner), Err(metadata::Error::Pinned)); assert_eq!(table.snapshot(), snapshot); assert_eq!(table.record(process), Ok(record)); assert_eq!(driver(&mut table).inventory(), inventory); assert_eq!(driver(&mut table).frames.read_byte(page, owner, 4095), Ok(0)); table.exit_current(9).unwrap(); control.borrow_mut().execution.kernel_bootstrap = true; assert_eq!(table.wait_child_outcome(process), Ok(Outcome::Exited(9))); assert_eq!(driver(&mut table).inventory(), baseline); }