indexbus_kit/embedded/
static_spsc.rs1use core::cell::UnsafeCell;
2use core::mem::MaybeUninit;
3use core::sync::atomic::{AtomicBool, Ordering};
4
5use crate::errors::{Error, Result};
6
7use indexbus_abi::layouts::SharedLayout;
8use indexbus_core::{init_shared_layout, split_spsc, SharedLayoutCell, SpscReceiver, SpscSender};
9
10struct StaticShared(UnsafeCell<MaybeUninit<SharedLayout>>);
11
12unsafe impl Sync for StaticShared {}
14
15static SHARED: StaticShared = StaticShared(UnsafeCell::new(MaybeUninit::uninit()));
16static TAKEN: AtomicBool = AtomicBool::new(false);
17
18pub fn static_spsc() -> Result<(SpscSender, SpscReceiver)> {
26 if TAKEN.swap(true, Ordering::AcqRel) {
29 return Err(Error::msg(
30 "static_spsc() is single-use (static region already taken)",
31 ));
32 }
33
34 let shared_ptr: *mut SharedLayout = unsafe {
35 let slot = SHARED.0.get();
36 (*slot).as_mut_ptr().write(core::mem::zeroed());
37 (*slot).as_mut_ptr()
38 };
39
40 let shared: &mut SharedLayout = unsafe { &mut *shared_ptr };
41 init_shared_layout(shared);
42
43 let cell = unsafe { SharedLayoutCell::from_ptr(shared_ptr) };
44 split_spsc(cell).map_err(Error::from)
45}