S409 · SOURCE-BOUND GATE EVIDENCE
S409 · Live offer SGI delivery
tam S409 implementation modülü → Operations --test hedefi ile bağlı tam focused test → ayrı Operations kaydı Bu sayfa yalnız S409 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.
S409Focused kod testiOperations id exactsource SHA exacttest target exact
operation: g8l-s409-live-offer-sgi-delivery-partial
uygulama/model · focused test · Operations · 3 exact excerpt
sequence-bound=true · implementation-bound=true
01 · Yürütme / doğrulama kodu
Kapının gerçek repository sözleşmesi
tam dosyaL1–L343
kernel/src/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s409_live_offer_sgi_delivery.rs::S409 live offer sgi delivery implementation
#![allow(unexpected_cfgs)]
//! S409 CPU0 SGI3 delivery, live-token validation, and exact raw EOI.
//!
//! S408 publishes a send receipt before issuing dedicated SGI3. S409 owns that
//! interrupt on CPU0, matches the send receipt to the pending S407 offer and
//! the active shared S247 exclusive token, writes the raw IAR value to EOI once,
//! and retains one linear delivery receipt. Admission remains a later gate.
use crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s407_live_exclusion_offer_publication::G8lS407LiveExclusionOffer;
use crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s408_live_offer_sgi_sender::{
G8lS408LiveOfferSgiSendReceipt, S408_DIRECT_SCHEDULER_ACCESS_SITES,
S408_EXPECTED_COMMAND, S408_EXPECTED_RAW_ACK, S408_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES,
S408_SGI_INTID, S408_SOURCE_AUDIT_UNITS, S408_SOURCE_CPU1,
S408_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES, S408_TARGET_CPU0,
S408_UNROUTED_DIRECT_ACCESS_SITES,
};
pub const S409_SOURCE_AUDIT_UNITS: usize = S408_SOURCE_AUDIT_UNITS;
pub const S409_DIRECT_SCHEDULER_ACCESS_SITES: usize = S408_DIRECT_SCHEDULER_ACCESS_SITES;
pub const S409_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES: usize =
S408_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES;
pub const S409_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES: usize =
S408_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES;
pub const S409_UNROUTED_DIRECT_ACCESS_SITES: usize = S408_UNROUTED_DIRECT_ACCESS_SITES;
pub const S409_TARGET_CPU0: usize = S408_TARGET_CPU0;
pub const S409_PRODUCTION_IRQ_HANDLER_CALLSITES: usize = 1;
pub const S409_DELIVERY_RECEIPT_SLOT_CAPACITY: usize = 1;
pub const S409_IRQ_DELIVERY_COMPLETE: bool = true;
pub const S409_ADMISSION_CONSUMER_COMPLETE: bool = false;
pub const S409_END_TO_END_EXCLUSION_ADMISSION_COMPLETE: bool = false;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum G8lS409LiveOfferSgiDeliveryError {
InvalidPhase,
WrongReceiverCpu,
WrongInterruptId,
WrongInterruptSource,
SendReceiptDrift,
OfferBindingDrift,
GateTokenMismatch,
RawEoiMismatch,
}
#[derive(Debug, PartialEq, Eq)]
pub struct G8lS409LiveOfferSgiAcknowledgement {
raw_ack: u32,
attempt_id: u64,
provider_request_id: u64,
exclusive_token: u64,
}
#[derive(Debug, PartialEq, Eq)]
pub struct G8lS409LiveOfferSgiDeliveryReceipt {
raw_ack: u32,
raw_eoi: u32,
attempt_id: u64,
provider_request_id: u64,
exclusive_token: u64,
}
impl G8lS409LiveOfferSgiDeliveryReceipt {
pub const fn raw_ack(&self) -> u32 {
self.raw_ack
}
pub const fn raw_eoi(&self) -> u32 {
self.raw_eoi
}
pub const fn attempt_id(&self) -> u64 {
self.attempt_id
}
pub const fn provider_request_id(&self) -> u64 {
self.provider_request_id
}
pub const fn exclusive_token(&self) -> u64 {
self.exclusive_token
}
pub const fn gate_token_matched_while_live(&self) -> bool {
true
}
pub const fn view(&self) -> G8lS409LiveOfferSgiDeliveryReceiptView {
G8lS409LiveOfferSgiDeliveryReceiptView {
raw_ack: self.raw_ack,
raw_eoi: self.raw_eoi,
attempt_id: self.attempt_id,
provider_request_id: self.provider_request_id,
exclusive_token: self.exclusive_token,
}
}
}
impl Drop for G8lS409LiveOfferSgiDeliveryReceipt {
fn drop(&mut self) {}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct G8lS409LiveOfferSgiDeliveryReceiptView {
raw_ack: u32,
raw_eoi: u32,
attempt_id: u64,
provider_request_id: u64,
exclusive_token: u64,
}
impl G8lS409LiveOfferSgiDeliveryReceiptView {
pub const fn raw_ack(&self) -> u32 {
self.raw_ack
}
pub const fn raw_eoi(&self) -> u32 {
self.raw_eoi
}
pub const fn attempt_id(&self) -> u64 {
self.attempt_id
}
pub const fn provider_request_id(&self) -> u64 {
self.provider_request_id
}
pub const fn exclusive_token(&self) -> u64 {
self.exclusive_token
}
pub const fn gate_token_matched_while_live(&self) -> bool {
true
}
}
#[derive(Debug)]
pub struct G8lS409LiveOfferSgiDeliveryState {
handling: bool,
receipt: Option<G8lS409LiveOfferSgiDeliveryReceipt>,
}
impl G8lS409LiveOfferSgiDeliveryState {
pub const fn new() -> Self {
Self {
handling: false,
receipt: None,
}
}
pub const fn receipt_pending(&self) -> bool {
self.receipt.is_some()
}
pub fn pending_receipt_view(&self) -> Option<G8lS409LiveOfferSgiDeliveryReceiptView> {
self.receipt
.as_ref()
.map(G8lS409LiveOfferSgiDeliveryReceipt::view)
}
pub fn begin_delivery(
&mut self,
receiver_cpu: usize,
raw_ack: u32,
send: G8lS408LiveOfferSgiSendReceipt,
offer: G8lS407LiveExclusionOffer,
active_exclusive_token: Option<u64>,
) -> Result<G8lS409LiveOfferSgiAcknowledgement, G8lS409LiveOfferSgiDeliveryError> {
if self.handling || self.receipt.is_some() {
return Err(G8lS409LiveOfferSgiDeliveryError::InvalidPhase);
}
if receiver_cpu != S409_TARGET_CPU0 {
return Err(G8lS409LiveOfferSgiDeliveryError::WrongReceiverCpu);
}
if raw_ack & 0x3ff != S408_SGI_INTID {
return Err(G8lS409LiveOfferSgiDeliveryError::WrongInterruptId);
}
if ((raw_ack >> 10) & 0x7) as usize != S408_SOURCE_CPU1 {
return Err(G8lS409LiveOfferSgiDeliveryError::WrongInterruptSource);
}
if raw_ack != S408_EXPECTED_RAW_ACK || send.command() != S408_EXPECTED_COMMAND {
return Err(G8lS409LiveOfferSgiDeliveryError::SendReceiptDrift);
}
if send.attempt_id() != offer.attempt_id
|| send.provider_request_id() != offer.provider_request_id
|| send.exclusive_token() != offer.exclusive_token
|| offer.source_cpu != S408_SOURCE_CPU1
|| offer.target_cpu != S409_TARGET_CPU0
|| !offer.requires_live_gate_match
|| offer.is_authority
|| offer.whole_scheduler_exclusion_proven
{
return Err(G8lS409LiveOfferSgiDeliveryError::OfferBindingDrift);
}
if active_exclusive_token != Some(offer.exclusive_token) {
return Err(G8lS409LiveOfferSgiDeliveryError::GateTokenMismatch);
}
self.handling = true;
Ok(G8lS409LiveOfferSgiAcknowledgement {
raw_ack,
attempt_id: offer.attempt_id,
provider_request_id: offer.provider_request_id,
exclusive_token: offer.exclusive_token,
})
}
pub fn complete_eoi(
&mut self,
acknowledgement: G8lS409LiveOfferSgiAcknowledgement,
raw_eoi: u32,
) -> Result<G8lS409LiveOfferSgiDeliveryReceiptView, G8lS409LiveOfferSgiDeliveryError> {
if !self.handling || self.receipt.is_some() {
return Err(G8lS409LiveOfferSgiDeliveryError::InvalidPhase);
}
if raw_eoi != acknowledgement.raw_ack {
return Err(G8lS409LiveOfferSgiDeliveryError::RawEoiMismatch);
}
let receipt = G8lS409LiveOfferSgiDeliveryReceipt {
raw_ack: acknowledgement.raw_ack,
raw_eoi,
attempt_id: acknowledgement.attempt_id,
provider_request_id: acknowledgement.provider_request_id,
exclusive_token: acknowledgement.exclusive_token,
};
let view = receipt.view();
self.receipt = Some(receipt);
self.handling = false;
Ok(view)
}
pub fn take_receipt(
&mut self,
caller_cpu: usize,
) -> Result<Option<G8lS409LiveOfferSgiDeliveryReceipt>, G8lS409LiveOfferSgiDeliveryError> {
if caller_cpu != S409_TARGET_CPU0 {
return Err(G8lS409LiveOfferSgiDeliveryError::WrongReceiverCpu);
}
Ok(self.receipt.take())
}
}
impl Default for G8lS409LiveOfferSgiDeliveryState {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum G8lS409LiveOfferSgiDeliveryServiceError<E> {
Delivery(G8lS409LiveOfferSgiDeliveryError),
Eoi(E),
}
pub fn service_s409_model_live_offer_sgi_delivery<E, EndOfInterrupt>(
delivery: &mut G8lS409LiveOfferSgiDeliveryState,
receiver_cpu: usize,
raw_ack: u32,
send: G8lS408LiveOfferSgiSendReceipt,
offer: G8lS407LiveExclusionOffer,
active_exclusive_token: Option<u64>,
mut end_of_interrupt: EndOfInterrupt,
) -> Result<G8lS409LiveOfferSgiDeliveryReceiptView, G8lS409LiveOfferSgiDeliveryServiceError<E>>
where
EndOfInterrupt: FnMut(u32) -> Result<(), E>,
{
let acknowledgement = delivery
.begin_delivery(receiver_cpu, raw_ack, send, offer, active_exclusive_token)
.map_err(G8lS409LiveOfferSgiDeliveryServiceError::Delivery)?;
end_of_interrupt(raw_ack).map_err(G8lS409LiveOfferSgiDeliveryServiceError::Eoi)?;
delivery
.complete_eoi(acknowledgement, raw_ack)
.map_err(G8lS409LiveOfferSgiDeliveryServiceError::Delivery)
}
#[cfg(all(target_arch = "aarch64", target_os = "none", feature = "board-rpi5"))]
static S409_PRODUCTION_DELIVERY: spin::Mutex<G8lS409LiveOfferSgiDeliveryState> =
spin::Mutex::new(G8lS409LiveOfferSgiDeliveryState::new());
/// Own SGI3. Every owned-path failure still writes exactly one fallback EOI.
#[cfg(all(target_arch = "aarch64", target_os = "none", feature = "board-rpi5"))]
pub fn try_handle_s409_live_offer_sgi_on_cpu0(ack: u32, int_id: u32) -> bool {
use crate::g8l_runtime_contract::CPU0;
if int_id != S408_SGI_INTID {
return false;
}
let mut eoi_written = false;
let result = (|| -> Result<(), ()> {
let send = crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s408_live_offer_sgi_sender::take_s408_live_offer_sgi_send_receipt_on_cpu0()
.map_err(|_| ())?
.ok_or(())?;
let offer = crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s407_live_exclusion_offer_publication::inspect_s407_live_exclusion_offer_on_cpu0()
.map_err(|_| ())?
.ok_or(())?;
let active_token = crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s246_whole_scheduler_read_access_guard::S247_PRODUCTION_WHOLE_SCHEDULER_ACCESS_GATE
.active_exclusive_token();
service_s409_model_live_offer_sgi_delivery(
&mut S409_PRODUCTION_DELIVERY.lock(),
crate::percpu::try_current_cpu_id().unwrap_or(usize::MAX),
ack,
send,
offer,
active_token,
|_| {
crate::arch::aarch64::gic::end_of_interrupt(ack);
eoi_written = true;
Ok::<(), ()>(())
},
)
.map(|_| ())
.map_err(|_| ())
})();
if result.is_ok() {
let candidate = crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s410_exclusion_admission_candidate_publication::service_s410_exclusion_admission_candidate_publication_on_cpu0();
debug_assert!(candidate.is_ok());
if candidate.is_ok() {
let admission = crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s411_ephemeral_exclusion_admission_constructor::service_s411_ephemeral_exclusion_admission_constructor_on_cpu0();
debug_assert!(admission.is_ok());
if admission.is_ok() {
let join = unsafe {
crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s413_exclusion_gated_s243_join::service_s413_exclusion_gated_s243_join_on_cpu0()
};
debug_assert!(join.is_ok());
if let Ok(crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s413_exclusion_gated_s243_join::G8lS413ExclusionGatedJoinOutcome::Published(receipt)) = join {
let ack = crate::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s414_s243_join_ack_publication::service_s414_s243_join_ack_publication_on_cpu0(receipt);
debug_assert!(ack.is_ok());
}
}
}
}
if !eoi_written {
crate::arch::aarch64::gic::end_of_interrupt(ack);
}
debug_assert!(result.is_ok() && crate::percpu::try_current_cpu_id() == Some(CPU0));
true
}
#[cfg(all(target_arch = "aarch64", target_os = "none", feature = "board-rpi5"))]
pub fn take_s409_live_offer_sgi_delivery_receipt_on_cpu0(
) -> Result<Option<G8lS409LiveOfferSgiDeliveryReceipt>, G8lS409LiveOfferSgiDeliveryError> {
use crate::g8l_runtime_contract::CPU0;
S409_PRODUCTION_DELIVERY.lock().take_receipt(CPU0)
}
#[cfg(all(target_arch = "aarch64", target_os = "none", feature = "board-rpi5"))]
pub fn inspect_s409_live_offer_sgi_delivery_receipt_on_cpu0(
) -> Result<Option<G8lS409LiveOfferSgiDeliveryReceiptView>, G8lS409LiveOfferSgiDeliveryError> {
use crate::g8l_runtime_contract::CPU0;
if crate::percpu::try_current_cpu_id() != Some(CPU0) {
return Err(G8lS409LiveOfferSgiDeliveryError::WrongReceiverCpu);
}
Ok(S409_PRODUCTION_DELIVERY.lock().pending_receipt_view())
}
snippet sha256: 1f89b0022888…file sha256: 1f89b0022888…
02 · Doğrulayan test kodu
Operations komutuna bağlı focused test
tam dosyaL1–L377
simulation/tests/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s409_live_offer_sgi_delivery.rs::S409 live offer sgi delivery focused tests
#![recursion_limit = "256"]
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s244_whole_scheduler_exclusion_admission_request::{
service_s245_exclusion_admission_request, G8lS245WholeSchedulerExclusionAdmissionRequestState,
S245_SOURCE_CPU0, S245_TARGET_CPU1,
};
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s246_whole_scheduler_read_access_guard::G8lS247WholeSchedulerAccessGate;
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s402_provider_invocation_observation_publication::{
service_s402_model_provider_invocation_observation_publication,
G8lS402ProviderInvocationObservationState,
};
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s404_scoped_authority_request_publication::{
service_s404_model_scoped_authority_request_publication,
G8lS404ScopedAuthorityRequestState,
};
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s407_live_exclusion_offer_publication::{
try_publish_s407_model_live_exclusion_offer, G8lS407LiveExclusionOffer,
G8lS407LiveExclusionOfferState,
};
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s408_live_offer_sgi_sender::{
service_s408_model_live_offer_sgi_send, G8lS408LiveOfferSgiSendReceipt,
G8lS408LiveOfferSgiSenderState, S408_DIRECT_SCHEDULER_ACCESS_SITES,
S408_EXPECTED_ENABLE, S408_EXPECTED_RAW_ACK, S408_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES,
S408_SOURCE_AUDIT_UNITS, S408_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES,
S408_UNROUTED_DIRECT_ACCESS_SITES,
};
use aselsan_microkernel_simulation::g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s409_live_offer_sgi_delivery::*;
fn live_send() -> (
G8lS247WholeSchedulerAccessGate,
G8lS407LiveExclusionOffer,
G8lS408LiveOfferSgiSendReceipt,
) {
let gate = G8lS247WholeSchedulerAccessGate::new();
let mut providers = G8lS245WholeSchedulerExclusionAdmissionRequestState::new();
service_s245_exclusion_admission_request(&mut providers, S245_SOURCE_CPU0, true, true).unwrap();
let mut observations = G8lS402ProviderInvocationObservationState::new();
service_s402_model_provider_invocation_observation_publication(
&mut observations,
&gate,
&mut providers,
S245_TARGET_CPU1,
)
.unwrap();
let mut scoped = G8lS404ScopedAuthorityRequestState::new();
service_s404_model_scoped_authority_request_publication(
&mut scoped,
&mut observations,
S245_SOURCE_CPU0,
)
.unwrap();
service_s245_exclusion_admission_request(&mut providers, S245_SOURCE_CPU0, true, true).unwrap();
let mut offers = G8lS407LiveExclusionOfferState::new();
let offered = try_publish_s407_model_live_exclusion_offer(
&mut offers,
&gate,
&mut providers,
&mut scoped,
S245_TARGET_CPU1,
)
.unwrap()
.unwrap();
let offer = offered.offer();
let mut sender = G8lS408LiveOfferSgiSenderState::new();
sender
.prepare_receiver(0, 1, S408_EXPECTED_ENABLE, 1, 0)
.unwrap();
let send = service_s408_model_live_offer_sgi_send(&mut sender, 1, &offered).unwrap();
core::mem::forget(offered);
(gate, offer, send)
}
fn module_source() -> &'static str {
include_str!("../../kernel/src/g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s409_live_offer_sgi_delivery.rs")
}
fn exception_source() -> &'static str {
include_str!("../../kernel/src/arch/aarch64/exceptions.rs")
}
fn kernel_main_source() -> &'static str {
include_str!("../../kernel/src/main.rs")
}
fn simulation_lib_source() -> &'static str {
include_str!("../src/lib.rs")
}
#[test]
fn constants_promote_exact_sgi3_irq_delivery_only() {
assert_eq!(S409_SOURCE_AUDIT_UNITS, 7);
assert_eq!(S409_DIRECT_SCHEDULER_ACCESS_SITES, 113);
assert_eq!(S409_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES, 113);
assert_eq!(S409_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES, 113);
assert_eq!(S409_UNROUTED_DIRECT_ACCESS_SITES, 0);
assert_eq!(S409_PRODUCTION_IRQ_HANDLER_CALLSITES, 1);
assert_eq!(S409_DELIVERY_RECEIPT_SLOT_CAPACITY, 1);
assert!(S409_IRQ_DELIVERY_COMPLETE);
assert!(!S409_ADMISSION_CONSUMER_COMPLETE);
assert!(!S409_END_TO_END_EXCLUSION_ADMISSION_COMPLETE);
}
#[test]
fn s408_is_the_exact_sender_predecessor() {
assert_eq!(S409_SOURCE_AUDIT_UNITS, S408_SOURCE_AUDIT_UNITS);
assert_eq!(
S409_DIRECT_SCHEDULER_ACCESS_SITES,
S408_DIRECT_SCHEDULER_ACCESS_SITES
);
assert_eq!(
S409_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES,
S408_SOURCE_MODEL_COVERED_DIRECT_ACCESS_SITES
);
assert_eq!(
S409_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES,
S408_PRODUCTION_GUARDED_DIRECT_ACCESS_SITES
);
assert_eq!(
S409_UNROUTED_DIRECT_ACCESS_SITES,
S408_UNROUTED_DIRECT_ACCESS_SITES
);
}
#[test]
fn exact_raw_ack_live_offer_and_gate_token_publish_post_eoi_receipt() {
let (gate, offer, send) = live_send();
let mut delivery = G8lS409LiveOfferSgiDeliveryState::new();
let mut eoi_count = 0;
let receipt = service_s409_model_live_offer_sgi_delivery(
&mut delivery,
S409_TARGET_CPU0,
S408_EXPECTED_RAW_ACK,
send,
offer,
gate.active_exclusive_token(),
|raw| {
assert_eq!(raw, S408_EXPECTED_RAW_ACK);
eoi_count += 1;
Ok::<(), ()>(())
},
)
.unwrap();
assert_eq!(eoi_count, 1);
assert_eq!(receipt.raw_ack(), S408_EXPECTED_RAW_ACK);
assert_eq!(receipt.raw_eoi(), S408_EXPECTED_RAW_ACK);
assert_eq!(receipt.attempt_id(), 1);
assert_eq!(receipt.provider_request_id(), 2);
assert_eq!(receipt.exclusive_token(), 2);
assert!(receipt.gate_token_matched_while_live());
assert!(delivery.receipt_pending());
}
#[test]
fn wrong_receiver_raw_intid_source_or_gate_token_fails_before_eoi() {
for (cpu, raw, token, expected) in [
(
1,
S408_EXPECTED_RAW_ACK,
Some(2),
G8lS409LiveOfferSgiDeliveryError::WrongReceiverCpu,
),
(
0,
4,
Some(2),
G8lS409LiveOfferSgiDeliveryError::WrongInterruptId,
),
(
0,
3,
Some(2),
G8lS409LiveOfferSgiDeliveryError::WrongInterruptSource,
),
(
0,
S408_EXPECTED_RAW_ACK,
Some(9),
G8lS409LiveOfferSgiDeliveryError::GateTokenMismatch,
),
] {
let (_gate, offer, send) = live_send();
let mut delivery = G8lS409LiveOfferSgiDeliveryState::new();
let mut eoi_count = 0;
assert_eq!(
service_s409_model_live_offer_sgi_delivery(
&mut delivery,
cpu,
raw,
send,
offer,
token,
|_| {
eoi_count += 1;
Ok::<(), ()>(())
}
),
Err(G8lS409LiveOfferSgiDeliveryServiceError::Delivery(expected))
);
assert_eq!(eoi_count, 0);
assert!(!delivery.receipt_pending());
}
}
#[test]
fn send_receipt_offer_identity_drift_fails_before_eoi() {
let (_gate, mut offer, send) = live_send();
offer.provider_request_id += 1;
let mut delivery = G8lS409LiveOfferSgiDeliveryState::new();
assert!(matches!(
service_s409_model_live_offer_sgi_delivery(
&mut delivery,
0,
S408_EXPECTED_RAW_ACK,
send,
offer,
Some(2),
|_| Ok::<(), ()>(())
),
Err(G8lS409LiveOfferSgiDeliveryServiceError::Delivery(
G8lS409LiveOfferSgiDeliveryError::OfferBindingDrift
))
));
}
#[test]
fn eoi_failure_does_not_publish_delivery_receipt() {
let (gate, offer, send) = live_send();
let mut delivery = G8lS409LiveOfferSgiDeliveryState::new();
assert!(matches!(
service_s409_model_live_offer_sgi_delivery(
&mut delivery,
0,
S408_EXPECTED_RAW_ACK,
send,
offer,
gate.active_exclusive_token(),
|_| Err("eoi")
),
Err(G8lS409LiveOfferSgiDeliveryServiceError::Eoi("eoi"))
));
assert!(!delivery.receipt_pending());
}
#[test]
fn duplicate_delivery_is_rejected_without_second_eoi() {
let (gate, offer, send) = live_send();
let mut delivery = G8lS409LiveOfferSgiDeliveryState::new();
service_s409_model_live_offer_sgi_delivery(
&mut delivery,
0,
S408_EXPECTED_RAW_ACK,
send,
offer,
gate.active_exclusive_token(),
|_| Ok::<(), ()>(()),
)
.unwrap();
let mut second_eoi = 0;
assert!(matches!(
service_s409_model_live_offer_sgi_delivery(
&mut delivery,
0,
S408_EXPECTED_RAW_ACK,
send,
offer,
gate.active_exclusive_token(),
|_| {
second_eoi += 1;
Ok::<(), ()>(())
}
),
Err(G8lS409LiveOfferSgiDeliveryServiceError::Delivery(
G8lS409LiveOfferSgiDeliveryError::InvalidPhase
))
));
assert_eq!(second_eoi, 0);
}
#[test]
fn receipt_is_linear_and_cpu0_take_is_one_shot() {
assert!(core::mem::needs_drop::<G8lS409LiveOfferSgiDeliveryReceipt>());
let (gate, offer, send) = live_send();
let mut delivery = G8lS409LiveOfferSgiDeliveryState::new();
service_s409_model_live_offer_sgi_delivery(
&mut delivery,
0,
S408_EXPECTED_RAW_ACK,
send,
offer,
gate.active_exclusive_token(),
|_| Ok::<(), ()>(()),
)
.unwrap();
assert!(matches!(
delivery.take_receipt(1),
Err(G8lS409LiveOfferSgiDeliveryError::WrongReceiverCpu)
));
assert!(delivery.take_receipt(0).unwrap().is_some());
assert!(delivery.take_receipt(0).unwrap().is_none());
}
#[test]
fn model_orders_validation_before_eoi_before_receipt_publish() {
let source = module_source();
let start = source
.find("pub fn service_s409_model_live_offer_sgi_delivery")
.unwrap();
let function: String = source[start..].split_whitespace().collect();
let validate = function.find("delivery.begin_delivery(").unwrap();
let eoi = function.find("end_of_interrupt(raw_ack)").unwrap();
let publish = function.find("delivery.complete_eoi(").unwrap();
assert!(validate < eoi && eoi < publish);
}
#[test]
fn irq_interceptor_owns_sgi3_before_s240_sgi2_and_returns_immediately() {
let source = exception_source();
let s409 = source
.find("try_handle_s409_live_offer_sgi_on_cpu0")
.unwrap();
let s240 = source
.find("try_handle_s179_notification_sgi_on_cpu0")
.unwrap();
assert!(s409 < s240);
assert!(source[s409..s240].contains("return resume_ctx"));
}
#[test]
fn production_handler_matches_offer_and_shared_s247_token_before_raw_eoi() {
let source = module_source();
let start = source
.find("pub fn try_handle_s409_live_offer_sgi_on_cpu0")
.unwrap();
let function = &source[start..];
let offer = function
.find("inspect_s407_live_exclusion_offer_on_cpu0")
.unwrap();
let gate = function
.find("S247_PRODUCTION_WHOLE_SCHEDULER_ACCESS_GATE")
.unwrap();
let eoi = function.find("end_of_interrupt(ack)").unwrap();
assert!(offer < eoi && gate < eoi);
}
#[test]
fn production_handler_writes_one_fallback_eoi_on_any_owned_sgi3_failure() {
let source = module_source();
assert!(source.contains("if !eoi_written"));
assert_eq!(source.matches("end_of_interrupt(ack)").count(), 2);
}
#[test]
fn s409_does_not_publish_admission_or_enter_s243() {
let source = module_source();
for forbidden in [
"publish_s244",
"service_s243_deferred_authority_receipt_join",
"addr_of!(",
"addr_of_mut!(",
] {
assert!(
!source.contains(forbidden),
"forbidden promotion: {forbidden}"
);
}
}
#[test]
fn s409_and_its_exact_s410_candidate_publisher_are_registered_separately() {
let s409 = "g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s409_live_offer_sgi_delivery";
let s410 = "g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s410_exclusion_admission_candidate_publication";
assert!(kernel_main_source().contains(&format!("mod {s409};")));
assert!(simulation_lib_source().contains(&format!("pub mod {s409};")));
assert!(kernel_main_source().contains(&format!("mod {s410};")));
assert!(simulation_lib_source().contains(&format!("pub mod {s410};")));
}
snippet sha256: 0ad35e21102b…file sha256: 0ad35e21102b…
03 · Kapı kimlik kaydı
Operations sıra, kimlik ve başlık bağı
tam Operations kaydıL236–L252
website/src/lib/operations.ts::g8l-s409-live-offer-sgi-delivery-partial
{
id: "g8l-s409-live-offer-sgi-delivery-partial",
sequence: 409,
slug: "live_offer_sgi_delivery",
title: "Live offer SGI delivery",
focusedTests: 14,
sourceBytes: 13539,
sourceSha256:
"1f89b002288893a8bf71e9ecbf78e10b967bcbb5706fb89c2d8677da7805073b",
testBytes: 13270,
testSha256:
"0ad35e21102b3ba9ded8aee0c1154a7c5b70041949fd45ebcb13d0414db81696",
acceptance:
"CPU0 IRQ interceptor exact SGI3/raw ACK/source tuple'ını doğrular, typed delivery receipt'i capacity-one slot'a koyar ve raw EOI sırasını korur.",
retainedBoundary:
"IRQ delivery tamamdır; admission candidate consumer bu kapıda çalıştırılmaz.",
},snippet sha256: 93fd6181afbf…file sha256: 9726dbf00f84…
Focused test komutu
CARGO_INCREMENTAL=0 cargo test -p aselsan_microkernel_simulation --test g8l_target_dispatch_scheduler_owner_scheduler_mutation_production_migration_lifecycle_s409_live_offer_sgi_delivery -- --test-threads=1proof: docs/M8.1-RPi5-G8l-S409-Live-Offer-SGI-Delivery-Proof.md
Registry schema v5 · generator
website/scripts/generate-code-gates.mjs · Tam SHA-256: 91d38c7b6222f0b4c117be786454853543da55a160e543d9b951057cc20dcc06