use core::cell::UnsafeCell;
use core::mem::MaybeUninit;
use core::ptr::NonNull;
use core::sync::atomic::{AtomicU64, AtomicUsize};
use market_square::area::{AreaInner, AreaReader, AreaWriter, SUSPENDED_BIT, finish_init};
use market_square::arithmetics::AtomicType;
use market_square::cache_padded::CachePadded;
use market_square::map::{SimpleLPHashMap, Slot, EMPTY};
use market_square::storage::{StaticStorage, StaticSliceStorage};
const BUFFER_CAPACITY: usize = 16;
const READER_CAPACITY: usize = 4;
static mut BUFFER: [UnsafeCell<MaybeUninit<u64>>; BUFFER_CAPACITY] =
unsafe { MaybeUninit::uninit().assume_init() };
static mut READER_GENS: MaybeUninit<[Slot<CachePadded<AtomicU64>>; READER_CAPACITY]> =
MaybeUninit::uninit();
static mut DESTROY_STAGES: AtomicUsize = AtomicUsize::new(2);
static mut READER_KEEP_ALLOC_TICKETS: AtomicUsize = AtomicUsize::new(0);
static mut READER_STAGE_TICKETS: AtomicUsize = AtomicUsize::new(0);
static mut AREA_INNER: MaybeUninit<
AreaInner<
u64,
StaticSliceStorage<Slot<CachePadded<AtomicType>>>,
StaticSliceStorage<UnsafeCell<MaybeUninit<u64>>>,
StaticStorage<AtomicUsize>,
>
> = MaybeUninit::uninit();
unsafe fn init_area() -> (
AreaWriter<
u64,
StaticStorage<AreaInner<
u64,
StaticSliceStorage<Slot<CachePadded<AtomicType>>>,
StaticSliceStorage<UnsafeCell<MaybeUninit<u64>>>,
StaticStorage<AtomicUsize>,
>>,
StaticSliceStorage<Slot<CachePadded<AtomicType>>>,
StaticSliceStorage<UnsafeCell<MaybeUninit<u64>>>,
StaticStorage<AtomicUsize>,
>,
AreaReader<
u64,
StaticStorage<AreaInner<
u64,
StaticSliceStorage<Slot<CachePadded<AtomicType>>>,
StaticSliceStorage<UnsafeCell<MaybeUninit<u64>>>,
StaticStorage<AtomicUsize>,
>>,
StaticSliceStorage<Slot<CachePadded<AtomicType>>>,
StaticSliceStorage<UnsafeCell<MaybeUninit<u64>>>,
StaticStorage<AtomicUsize>,
>,
) {
unsafe {
core::ptr::write(&raw mut BUFFER, [const { UnsafeCell::new(MaybeUninit::uninit()) }; BUFFER_CAPACITY]);
core::ptr::write(&raw mut READER_GENS as *mut [Slot<CachePadded<AtomicType>>; READER_CAPACITY], [const {
Slot {
key: AtomicType::new(EMPTY),
value: UnsafeCell::new(MaybeUninit::new(CachePadded::new(AtomicType::new(SUSPENDED_BIT)))),
}
}; READER_CAPACITY]);
DESTROY_STAGES = AtomicUsize::new(2);
READER_KEEP_ALLOC_TICKETS = AtomicUsize::new(0);
READER_STAGE_TICKETS = AtomicUsize::new(0);
let buffer_storage = StaticSliceStorage::from_raw(
NonNull::new_unchecked(&raw mut BUFFER as *mut UnsafeCell<MaybeUninit<u64>>),
BUFFER_CAPACITY,
);
let reader_gens_storage = StaticSliceStorage::from_raw(
NonNull::new_unchecked(&raw mut READER_GENS as *mut Slot<CachePadded<AtomicType>>),
READER_CAPACITY,
);
let destroy_stages_storage = StaticStorage::from_raw(
NonNull::new_unchecked(&raw mut DESTROY_STAGES)
);
let reader_keep_alloc_storage = StaticStorage::from_raw(
NonNull::new_unchecked(&raw mut READER_KEEP_ALLOC_TICKETS)
);
let reader_stage_storage = StaticStorage::from_raw(
NonNull::new_unchecked(&raw mut READER_STAGE_TICKETS)
);
let reader_gens_map = SimpleLPHashMap::from_storage(reader_gens_storage);
AreaInner::init(
&raw mut AREA_INNER as *mut AreaInner<
u64,
StaticSliceStorage<Slot<CachePadded<AtomicType>>>,
StaticSliceStorage<UnsafeCell<MaybeUninit<u64>>>,
StaticStorage<AtomicUsize>,
>,
reader_gens_map,
buffer_storage,
destroy_stages_storage,
reader_keep_alloc_storage,
reader_stage_storage,
);
let area_storage = StaticStorage::from_raw(
NonNull::new_unchecked(&raw mut AREA_INNER as *mut AreaInner<
u64,
StaticSliceStorage<Slot<CachePadded<AtomicType>>>,
StaticSliceStorage<UnsafeCell<MaybeUninit<u64>>>,
StaticStorage<AtomicUsize>,
>)
);
finish_init(area_storage)
}
}
fn main() {
unsafe {
let (writer, mut reader) = init_area();
let mut reservation = writer.reserve::<()>(3).expect("Failed to reserve");
reservation.get_mut(0).unwrap().write(100);
reservation.get_mut(1).unwrap().write(200);
reservation.get_mut(2).unwrap().write(300);
reservation.publish_spin();
let slice = reader.read();
println!("Read {} messages", slice.len());
for (i, val) in slice.iter().enumerate() {
println!(" [{}] = {}", i, val);
}
let _ = slice.try_cleanup_old_slots::<()>();
println!("done!");
}
}