// NEW reusable three-member backend. The real typed bindings/backing owners // remain exclusively inside CompletionBank; no binding is reconstructed. struct OsK1060Member { identity: u64, context: os_k1060_context::Handle, thread: os_k1060_thread::ThreadId, ordinal: usize, retired: bool, } struct OsK1060SelectionPrepared { handoff: Option, epoch: u64, nonce: u64, arrived: bool, } struct OsK1060QueueReturnPrepared { token: Option, source: os_k1060_context::Handle, nonce: u64, observed: bool, } struct OsK1060QueueBackend { bank: os_k1060_context::CompletionBank, identity: u64, members: [Option; 3], failed_tick: Option, retirement_quarantined: bool, } impl OsK1060QueueBackend { #[allow(clippy::result_large_err)] fn new( bank: os_k1060_context::CompletionBank, ) -> Result< Self, ( os_k1060_queue::Error, os_k1060_context::CompletionBank, ), > { let snapshot = bank.handoff().bank().snapshot(); if bank.quarantined() || bank.observation().is_some() || bank.handoff().quarantined() || bank.handoff().stage().is_some() || snapshot.retained != 3 || snapshot.active != 0 || snapshot.ready != 3 || snapshot.quarantined != 0 || snapshot.faulted || snapshot.retained_switch || snapshot.retained_capture { return Err((os_k1060_queue::Error::State, bank)); } let e = bank .handoff() .bank() .with_backend_observation(|b| os_k1060_context::Backend::execution(b)); if e.cpu != 0 || e.daif & 128 == 0 || e.in_irq || !e.fp_enabled || e.critical_depth != 0 || !e.safe_point || e.thread.is_some() { return Err((os_k1060_queue::Error::Context, bank)); } unsafe extern "C" { fn __os_k1060_backend_identity() -> u64; } let identity = unsafe { __os_k1060_backend_identity() }; if identity == 0 { return Err((os_k1060_queue::Error::Exhausted, bank)); } Ok(Self { bank, identity, members: [None; 3], failed_tick: None, retirement_quarantined: false, }) } fn issue( &mut self, handle: os_k1060_context::Handle, ordinal: usize, ) -> Result { if self.retirement_quarantined { return Err(os_k1060_queue::Error::Quarantined); } if ordinal >= 3 || self.members[ordinal].is_some() || self.members.contains(&Some(handle)) { return Err(os_k1060_queue::Error::Duplicate); } let o = self .bank .os_k1060_observe_member(handle) .map_err(|_| os_k1060_queue::Error::Backend)?; if o.thread.state != os_k1060_thread::State::Ready || o.context.state != os_k1060_context::State::Ready { return Err(os_k1060_queue::Error::State); } self.members[ordinal] = Some(handle); Ok(OsK1060Member { identity: self.identity, context: handle, thread: o.thread.id, ordinal, retired: false, }) } fn member( &self, member: &OsK1060Member, ) -> Result { if self.retirement_quarantined { return Err(os_k1060_queue::Error::Quarantined); } if member.retired { return Err(os_k1060_queue::Error::State); } if member.identity != self.identity || member.ordinal >= 3 || self.members[member.ordinal] != Some(member.context) { return Err(os_k1060_queue::Error::Stale); } let o = self .bank .os_k1060_observe_member(member.context) .map_err(|_| os_k1060_queue::Error::Backend)?; if o.thread.id != member.thread || o.context.thread != member.thread { return Err(os_k1060_queue::Error::Stale); } Ok(o) } } unsafe impl os_k1060_queue::Backend for OsK1060QueueBackend { type Member = OsK1060Member; type Prepared = OsK1060SelectionPrepared; type Tick = B::QueueTick; fn execution(&self) -> os_k1060_queue::Execution { let e = self .bank .handoff() .bank() .with_backend_observation(|b| os_k1060_context::Backend::execution(b)); os_k1060_queue::Execution { cpu: e.cpu, masked: e.daif & 128 != 0, in_irq: e.in_irq, thread: e.thread, root: e.root, } } fn observe( &self, m: &Self::Member, ) -> Result { self.member(m) } fn tick( &self, t: &Self::Tick, ) -> Result { self.bank.os_k1060_tick(t) } fn consume_tick(&mut self, t: Self::Tick) { if let Err((_e, actual)) = self.bank.os_k1060_consume_tick(t) { self.failed_tick = Some(actual); park(); } } fn prepare( &mut self, source: Option<&Self::Member>, target: &Self::Member, epoch: u64, d: os_k1060_queue::Disposition, ) -> Result { self.member(target)?; if let Some(source) = source { self.member(source)?; } let capture = if source.is_some() { Some( self.bank .os_k1060_capture() .map_err(|_| os_k1060_queue::Error::Backend)?, ) } else { None }; let bank = self .bank .quiescent() .map_err(|_| os_k1060_queue::Error::Busy)?; let handoff = match source { None => bank.start(target.context), Some(source) => match d { os_k1060_queue::Disposition::Ready => { bank.cooperate(source.context, target.context, capture.unwrap()) } os_k1060_queue::Disposition::Sleeping => { bank.sleep_to(source.context, target.context, capture.unwrap()) } }, } .map_err(|_| os_k1060_queue::Error::Backend)?; Ok(OsK1060SelectionPrepared { handoff: Some(handoff), epoch, nonce: 0, arrived: false, }) } fn commit( &mut self, _: &mut Self::Prepared, _: Option<&Self::Member>, _: &Self::Member, _: u64, _: os_k1060_queue::Disposition, ) -> Result<(), os_k1060_queue::Failure> { Err(os_k1060_queue::Failure { error: os_k1060_queue::Error::Context, phase: os_k1060_context::FailurePhase::BeforeSwitch, }) } fn finish(&mut self, p: Self::Prepared) -> Result<(), (os_k1060_queue::Error, Self::Prepared)> { if !p.arrived || p.handoff.is_some() { Err((os_k1060_queue::Error::State, p)) } else { Ok(()) } } fn abort( &mut self, mut p: Self::Prepared, ) -> Result<(), (os_k1060_queue::Error, Self::Prepared)> { let b = match self.bank.quiescent() { Ok(b) => b, Err(_) => return Err((os_k1060_queue::Error::Busy, p)), }; let t = p.handoff.take().unwrap(); match b.abort(t) { Ok(()) => Ok(()), Err(os_k1060_context::HandoffFailure::Before(_, t)) => { p.handoff = Some(t); Err((os_k1060_queue::Error::Backend, p)) } Err(os_k1060_context::HandoffFailure::Quarantined(_)) => { Err((os_k1060_queue::Error::Backend, p)) } } } } unsafe impl os_k1060_queue::SelectionHandoffBackend for OsK1060QueueBackend { fn depart( &mut self, p: &mut Self::Prepared, _: Option<&Self::Member>, _: &Self::Member, epoch: u64, _: os_k1060_queue::Disposition, nonce: u64, ) -> Result<(), os_k1060_queue::Failure> { if p.epoch != epoch || p.nonce != 0 || nonce == 0 { return Err(os_k1060_queue::Failure { error: os_k1060_queue::Error::Stale, phase: os_k1060_context::FailurePhase::BeforeSwitch, }); } let b = match self.bank.quiescent() { Ok(b) => b, Err(_) => { return Err(os_k1060_queue::Failure { error: os_k1060_queue::Error::Busy, phase: os_k1060_context::FailurePhase::BeforeSwitch, }); } }; let t = p.handoff.take().unwrap(); match b.depart(t) { Ok(t) => { p.handoff = Some(t); p.nonce = nonce; Ok(()) } Err(os_k1060_context::HandoffFailure::Before(_, t)) => { p.handoff = Some(t); Err(os_k1060_queue::Failure { error: os_k1060_queue::Error::Backend, phase: os_k1060_context::FailurePhase::BeforeSwitch, }) } Err(os_k1060_context::HandoffFailure::Quarantined(_)) => Err(os_k1060_queue::Failure { error: os_k1060_queue::Error::Backend, phase: os_k1060_context::FailurePhase::AfterSwitch, }), } } fn arrive( &mut self, p: &mut Self::Prepared, target: &Self::Member, epoch: u64, nonce: u64, ) -> Result<(), os_k1060_queue::Error> { if p.epoch != epoch || p.nonce != nonce { return Err(os_k1060_queue::Error::Stale); } let b = self .bank .quiescent() .map_err(|_| os_k1060_queue::Error::Busy)?; let t = p.handoff.take().unwrap(); match b.landed(t) { Ok(()) => { p.arrived = true; self.member(target)?; Ok(()) } Err(os_k1060_context::HandoffFailure::Before(_, t)) => { p.handoff = Some(t); Err(os_k1060_queue::Error::Backend) } Err(os_k1060_context::HandoffFailure::Quarantined(_)) => { Err(os_k1060_queue::Error::Backend) } } } } unsafe impl os_k1060_queue::QueueCompletionBackend for OsK1060QueueBackend { type ReturnPrepared = OsK1060QueueReturnPrepared; fn prepare_exit( &mut self, source: &Self::Member, capture: os_k1060_context::Capture, ) -> Result { self.member(source)?; let token = self .bank .prepare_return(source.context, capture) .map_err(|_| os_k1060_queue::Error::Backend)?; Ok(OsK1060QueueReturnPrepared { token: Some(token), source: source.context, nonce: 0, observed: false, }) } fn depart_exit( &mut self, p: &mut Self::ReturnPrepared, source: &Self::Member, nonce: u64, ) -> Result<(), os_k1060_queue::Failure> { if p.source != source.context || nonce == 0 || p.nonce != 0 { return Err(os_k1060_queue::Failure { error: os_k1060_queue::Error::Stale, phase: os_k1060_context::FailurePhase::BeforeSwitch, }); } let t = p.token.take().unwrap(); match self.bank.depart_return(t) { Ok(t) => { p.token = Some(t); p.nonce = nonce; Ok(()) } Err(os_k1060_context::ReturnFailure::Before(_, t)) => { p.token = Some(t); Err(os_k1060_queue::Failure { error: os_k1060_queue::Error::Backend, phase: os_k1060_context::FailurePhase::BeforeSwitch, }) } Err(os_k1060_context::ReturnFailure::Quarantined(_)) => Err(os_k1060_queue::Failure { error: os_k1060_queue::Error::Backend, phase: os_k1060_context::FailurePhase::AfterSwitch, }), } } fn returned_exit( &mut self, p: &mut Self::ReturnPrepared, source: &Self::Member, nonce: u64, ) -> Result<(), os_k1060_queue::Error> { if p.source != source.context || p.nonce != nonce { return Err(os_k1060_queue::Error::Stale); } self.bank .os_k1060_check_return_landing(p.token.as_ref().ok_or(os_k1060_queue::Error::State)?) .map_err(|_| os_k1060_queue::Error::Backend)?; p.observed = true; Ok(()) } fn finish_exit( &mut self, mut p: Self::ReturnPrepared, ) -> Result<(), (os_k1060_queue::Error, Self::ReturnPrepared)> { if !p.observed { return Err((os_k1060_queue::Error::State, p)); } let t = p.token.take().unwrap(); match self.bank.return_landed(t) { Ok(()) => Ok(()), Err(os_k1060_context::ReturnFailure::Before(_, t)) => { p.token = Some(t); Err((os_k1060_queue::Error::Backend, p)) } Err(os_k1060_context::ReturnFailure::Quarantined(_)) => { Err((os_k1060_queue::Error::Backend, p)) } } } fn abort_exit( &mut self, mut p: Self::ReturnPrepared, ) -> Result<(), (os_k1060_queue::Error, Self::ReturnPrepared)> { let t = p.token.take().unwrap(); match self.bank.abort_return(t) { Ok(()) => Ok(()), Err(os_k1060_context::ReturnFailure::Before(_, t)) => { p.token = Some(t); Err((os_k1060_queue::Error::Backend, p)) } Err(os_k1060_context::ReturnFailure::Quarantined(_)) => { Err((os_k1060_queue::Error::Backend, p)) } } } } impl OsK1060QueueBackend { fn retire_member( &mut self, mut m: OsK1060Member, ) -> Result { let observation = match self.member(&m) { Ok(o) => o, Err(e) => return Err((e, m)), }; let before = self .bank .handoff() .bank() .with_backend_observation(|b| os_k1060_context::Backend::execution(b)); let core = match self.bank.quiescent().and_then(|b| b.quiescent()) { Ok(core) => core, Err(_) => return Err((os_k1060_queue::Error::Busy, m)), }; if observation.thread.state != os_k1060_thread::State::Dead && core.os_k1040_cancel_inactive(m.context).is_err() { return Err((os_k1060_queue::Error::Backend, m)); } if core.retire(m.context).is_err() { return Err((os_k1060_queue::Error::Backend, m)); } // Frozen retirement has consumed the real Binding/Stack. A later // context failure retains only this explicitly retired logical member // and the exclusive bank; it never reconstructs a physical binding. m.retired = true; let after = self .bank .handoff() .bank() .with_backend_observation(|b| os_k1060_context::Backend::execution(b)); if after != before { self.retirement_quarantined = true; return Err((os_k1060_queue::Error::Quarantined, m)); } self.members[m.ordinal] = None; Ok(m) } } unsafe impl os_k1060_queue::QueueRetirementBackend for OsK1060QueueBackend { fn retire_withdrawn( &mut self, member: Self::Member, ) -> Result { self.retire_member(member) } } impl OsK1060QueueBackend { fn owner_words(&self) -> [u64; 17] { [ self.identity, &self.bank as *const _ as u64, core::mem::size_of_val(&self.bank) as u64, self.members.as_ptr() as u64, self.members.iter().filter(|m| m.is_some()).count() as u64, self.failed_tick .as_ref() .map_or(0, |t| t as *const B::QueueTick as u64), self.members[0].map_or(0, |h| h.bank()), self.members[0].map_or(0, |h| h.slot() as u64), self.members[0].map_or(0, |h| h.generation()), self.members[1].map_or(0, |h| h.bank()), self.members[1].map_or(0, |h| h.slot() as u64), self.members[1].map_or(0, |h| h.generation()), self.members[2].map_or(0, |h| h.bank()), self.members[2].map_or(0, |h| h.slot() as u64), self.members[2].map_or(0, |h| h.generation()), core::mem::size_of::() as u64, u64::from(self.retirement_quarantined), ] } } const fn os_k1060_backend_layout() -> [u64; 24] { use core::mem::{offset_of, size_of}; [ size_of::>() as u64, offset_of!(OsK1060QueueBackend, bank) as u64, offset_of!(OsK1060QueueBackend, identity) as u64, offset_of!(OsK1060QueueBackend, members) as u64, offset_of!(OsK1060QueueBackend, failed_tick) as u64, size_of::>() as u64, size_of::() as u64, offset_of!(OsK1060Member, identity) as u64, offset_of!(OsK1060Member, context) as u64, offset_of!(OsK1060Member, thread) as u64, offset_of!(OsK1060Member, ordinal) as u64, size_of::() as u64, offset_of!(OsK1060SelectionPrepared, handoff) as u64, offset_of!(OsK1060SelectionPrepared, epoch) as u64, offset_of!(OsK1060SelectionPrepared, nonce) as u64, offset_of!(OsK1060SelectionPrepared, arrived) as u64, size_of::() as u64, offset_of!(OsK1060QueueReturnPrepared, token) as u64, offset_of!(OsK1060QueueReturnPrepared, source) as u64, offset_of!(OsK1060QueueReturnPrepared, nonce) as u64, offset_of!(OsK1060QueueReturnPrepared, observed) as u64, size_of::>() as u64, offset_of!(OsK1060QueueBackend, retirement_quarantined) as u64, offset_of!(OsK1060Member, retired) as u64, ] } // Appended in the private real three-member Queue backend module. unsafe impl os_k1060_queue::WaitQueueServices for OsK1060QueueBackend { fn wait_physical_landing( &self, p: &Self::Prepared, m: &Self::Member, ) -> Result { if p.arrived || p.nonce == 0 || p.handoff.is_none() { return Err(os_k1060_queue::Error::State); } self.bank .handoff() .target_image(p.handoff.as_ref().unwrap()) .map_err(|_| os_k1060_queue::Error::Stale)?; self.member(m)?; self.bank .wait_guest_physical_landing(m.context) .map_err(|_| os_k1060_queue::Error::Context) } fn wait_capture(&self) -> Result { self.bank .os_k1060_capture() .map_err(|_| os_k1060_queue::Error::Context) } fn wait_custody( &mut self, m: &Self::Member, owned: &mut Option, resolve: bool, ) -> Result<(), os_k1060_queue::Failure> { self.member(m).map_err(|error| os_k1060_queue::Failure { error, phase: os_k1060_context::FailurePhase::BeforeSwitch, })?; self.bank .wait_guest_custody(m.context, owned, resolve) .map_err(|f| os_k1060_queue::Failure { error: if f.phase == os_k1060_context::FailurePhase::AfterSwitch { os_k1060_queue::Error::Quarantined } else { os_k1060_queue::Error::Backend }, phase: f.phase, }) } }