1#![cfg_attr(not(test), no_std)]
8use core::fmt;
9
10use descriptor::Descriptor;
11
12pub mod descriptor;
13mod vsizeof;
14pub use vsizeof::vsizeof;
15
16#[repr(transparent)]
17#[derive(Clone, Copy)]
18pub struct Scheduler(*mut ());
25
26#[derive(Clone, Copy)]
31#[repr(transparent)]
32pub struct CownPtr {
33 addr: *mut (),
35}
36unsafe impl Send for CownPtr {}
37unsafe impl Sync for CownPtr {}
38
39impl fmt::Pointer for CownPtr {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 write!(f, "{:p}", self.addr)
42 }
43}
44
45impl CownPtr {
46 pub fn addr(self) -> *mut () {
47 self.addr
48 }
49}
50
51#[repr(C)]
52#[derive(Debug)]
53pub struct OpaqueCown {
58 _marker: core::mem::MaybeUninit<[*const (); 3]>,
59}
60
61#[repr(transparent)]
62#[derive(Clone, Copy)]
63pub struct WorkPtr(*mut ());
64
65#[repr(C)]
66pub struct Slot {
67 pub cown: CownPtr,
68 _scheginfo: core::sync::atomic::AtomicUsize,
69}
70
71#[link(name = "boxcar_bindings")]
72extern "C" {
73
74 pub fn scheduler_get() -> Scheduler;
80
81 pub fn scheduler_init(schedular: Scheduler, n_threads: usize);
89
90 pub fn scheduler_run(schedular: Scheduler);
100
101 pub fn schedular_set_detect_leaks(detect_leaks: bool);
103 pub fn schedular_has_leaks() -> bool;
104
105 pub fn boxcars_acquire_object(cown: CownPtr);
106 pub fn boxcars_release_object(cown: CownPtr);
107
108 pub fn boxcars_allocate_cown(descriptor: &'static Descriptor) -> CownPtr;
109
110 pub fn enable_logging();
111 pub fn boxcars_dump_flight_recorder();
112
113 pub fn boxcars_sched_lambda(
114 f: extern "C" fn(WorkPtr),
115
116 cowns: *const CownPtr,
117 n_cowns: usize,
118
119 payload: *const (),
120 payload_size: usize,
121 );
122 pub fn boxcars_preinvoke(
123 work: WorkPtr,
124 slots: &mut *const Slot,
125 body: &mut *const (),
126 count: &mut usize,
127 );
128 pub fn boxcars_postinvoke(work: WorkPtr);
129
130 pub fn boxcar_log_cstr(ptr: *const core::ffi::c_char);
131 pub fn boxcar_log_usize(n: usize);
132 pub fn boxcar_log_ptr(p: *const ());
133 pub fn boxcar_log_endl();
134 pub fn boxcars_snmalloc_message(ptr: *const u8, len: usize);
136}
137
138#[test]
139fn cown_size_and_align() {
140 #[link(name = "boxcar_bindings")]
141 extern "C" {
142 fn boxcars_test_cown_info(size: &mut usize, align: &mut usize);
143 }
144 let mut size = 0;
145 let mut align = 0;
146 unsafe {
147 boxcars_test_cown_info(&mut size, &mut align);
148 }
149 assert_eq!(size, std::mem::size_of::<OpaqueCown>());
150 assert_eq!(align, std::mem::align_of::<OpaqueCown>())
151}
152
153#[test]
154fn slot_size_and_align() {
155 extern "C" {
156 fn boxcars_test_slot_info(size: &mut usize, align: &mut usize);
157 }
158
159 let (mut size, mut align) = (0, 0);
160 unsafe { boxcars_test_slot_info(&mut size, &mut align) };
161 assert_eq!(size, std::mem::size_of::<Slot>());
162 assert_eq!(align, std::mem::align_of::<Slot>());
163}