#![cfg_attr(not(test), no_std)]
use core::fmt;
use descriptor::Descriptor;
pub mod descriptor;
mod vsizeof;
pub use vsizeof::vsizeof;
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Scheduler(*mut ());
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct CownPtr {
addr: *mut (),
}
unsafe impl Send for CownPtr {}
unsafe impl Sync for CownPtr {}
impl fmt::Pointer for CownPtr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:p}", self.addr)
}
}
impl CownPtr {
pub fn addr(self) -> *mut () {
self.addr
}
}
#[repr(C)]
#[derive(Debug)]
pub struct OpaqueCown {
_marker: core::mem::MaybeUninit<[*const (); 3]>,
}
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct WorkPtr(*mut ());
#[repr(C)]
pub struct Slot {
pub cown: CownPtr,
_scheginfo: core::sync::atomic::AtomicUsize,
}
#[link(name = "boxcar_bindings")]
extern "C" {
pub fn scheduler_get() -> Scheduler;
pub fn scheduler_init(schedular: Scheduler, n_threads: usize);
pub fn scheduler_run(schedular: Scheduler);
pub fn schedular_set_detect_leaks(detect_leaks: bool);
pub fn schedular_has_leaks() -> bool;
pub fn boxcars_acquire_object(cown: CownPtr);
pub fn boxcars_release_object(cown: CownPtr);
pub fn boxcars_allocate_cown(descriptor: &'static Descriptor) -> CownPtr;
pub fn enable_logging();
pub fn boxcars_dump_flight_recorder();
pub fn boxcars_sched_lambda(
f: extern "C" fn(WorkPtr),
cowns: *const CownPtr,
n_cowns: usize,
payload: *const (),
payload_size: usize,
);
pub fn boxcars_preinvoke(
work: WorkPtr,
slots: &mut *const Slot,
body: &mut *const (),
count: &mut usize,
);
pub fn boxcars_postinvoke(work: WorkPtr);
pub fn boxcar_log_cstr(ptr: *const core::ffi::c_char);
pub fn boxcar_log_usize(n: usize);
pub fn boxcar_log_ptr(p: *const ());
pub fn boxcar_log_endl();
pub fn boxcars_snmalloc_message(ptr: *const u8, len: usize);
}
#[test]
fn cown_size_and_align() {
#[link(name = "boxcar_bindings")]
extern "C" {
fn boxcars_test_cown_info(size: &mut usize, align: &mut usize);
}
let mut size = 0;
let mut align = 0;
unsafe {
boxcars_test_cown_info(&mut size, &mut align);
}
assert_eq!(size, std::mem::size_of::<OpaqueCown>());
assert_eq!(align, std::mem::align_of::<OpaqueCown>())
}
#[test]
fn slot_size_and_align() {
extern "C" {
fn boxcars_test_slot_info(size: &mut usize, align: &mut usize);
}
let (mut size, mut align) = (0, 0);
unsafe { boxcars_test_slot_info(&mut size, &mut align) };
assert_eq!(size, std::mem::size_of::<Slot>());
assert_eq!(align, std::mem::align_of::<Slot>());
}