#![allow(unsafe_code)]
use owning_ref::StableAddress;
use shared_memory::EventSet;
use shared_memory::EventState;
use shared_memory::EventWait;
use shared_memory::SharedMem;
use shared_memory::SharedMemCast;
use shared_memory::Timeout;
use std::cell::UnsafeCell;
use std::mem;
use std::ops::Deref;
use std::ptr;
use std::slice;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::AtomicPtr;
use std::sync::atomic::AtomicU64;
use std::sync::atomic::AtomicUsize;
use crate::allocator::ShmemMetadata;
use crate::shared_channel::SharedChannel;
use crate::shared_channel::SharedReceiver;
use crate::shared_channel::SharedSender;
use crate::shared_rc::SharedRcContents;
use crate::AtomicSharedAddress;
use crate::AtomicSharedAddressRange;
use crate::ObjectOffset;
use crate::ObjectSize;
use crate::SharedAddress;
use crate::SharedAddressRange;
use crate::SharedBox;
use crate::SharedOption;
use crate::SharedRc;
use crate::SharedVec;
use crate::ShmemId;
use crate::ShmemName;
pub unsafe trait SharedMemRef {}
unsafe impl SharedMemRef for AtomicBool {}
unsafe impl SharedMemRef for AtomicUsize {}
unsafe impl SharedMemRef for AtomicU64 {}
unsafe impl<T> SharedMemRef for AtomicPtr<T> {}
unsafe impl SharedMemRef for () {}
unsafe impl<T1> SharedMemRef for (T1,) where T1: SharedMemRef {}
unsafe impl<T1, T2> SharedMemRef for (T1, T2)
where
T1: SharedMemRef,
T2: SharedMemRef,
{
}
unsafe impl<T1, T2, T3> SharedMemRef for (T1, T2, T3)
where
T1: SharedMemRef,
T2: SharedMemRef,
T3: SharedMemRef,
{
}
unsafe impl SharedMemRef for AtomicSharedAddress {}
unsafe impl SharedMemRef for AtomicSharedAddressRange {}
unsafe impl SharedMemRef for ShmemMetadata {}
unsafe impl<T: SharedMemCast> SharedMemRef for SharedChannel<T> {}
unsafe impl<T: SharedMemCast> SharedMemRef for SharedOption<T> {}
unsafe impl<T: SharedMemCast> SharedMemRef for SharedRc<T> {}
unsafe impl<T: SharedMemCast> SharedMemRef for SharedRcContents<T> {}
unsafe impl<T: SharedMemCast> SharedMemRef for SharedReceiver<T> {}
unsafe impl<T: SharedMemCast> SharedMemRef for SharedSender<T> {}
unsafe impl<T: SharedMemCast> SharedMemRef for SharedVec<T> {}
unsafe impl<T: SharedMemCast> SharedMemRef for Volatile<T> {}
unsafe impl SharedMemCast for AtomicSharedAddress {}
unsafe impl SharedMemCast for AtomicSharedAddressRange {}
unsafe impl SharedMemCast for ObjectOffset {}
unsafe impl SharedMemCast for ObjectSize {}
unsafe impl SharedMemCast for SharedAddress {}
unsafe impl SharedMemCast for SharedAddressRange {}
unsafe impl SharedMemCast for ShmemId {}
unsafe impl SharedMemCast for ShmemMetadata {}
unsafe impl SharedMemCast for ShmemName {}
unsafe impl<T: SharedMemCast> SharedMemCast for SharedBox<T> {}
unsafe impl<T: SharedMemCast> SharedMemCast for SharedChannel<T> {}
unsafe impl<T: SharedMemCast> SharedMemCast for SharedOption<T> {}
unsafe impl<T: SharedMemCast> SharedMemCast for SharedRc<T> {}
unsafe impl<T: SharedMemCast> SharedMemCast for SharedRcContents<T> {}
unsafe impl<T: SharedMemCast> SharedMemCast for SharedReceiver<T> {}
unsafe impl<T: SharedMemCast> SharedMemCast for SharedSender<T> {}
unsafe impl<T: SharedMemCast> SharedMemCast for SharedVec<T> {}
unsafe impl<T: SharedMemCast> SharedMemCast for Volatile<T> {}
unsafe impl<T: SharedMemCast> Sync for Volatile<T> {}
unsafe impl<T: SharedMemCast> Send for Volatile<T> {}
pub struct SyncSharedMem(*mut Volatile<u8>, usize, SharedMem);
impl SyncSharedMem {
pub fn from_shmem(shmem: SharedMem) -> SyncSharedMem {
let ptr = shmem.get_ptr() as *mut Volatile<u8>;
let size = shmem.get_size();
let result = SyncSharedMem(ptr, size, shmem);
result
}
pub fn set_event(&self, index: usize, state: EventState) {
let this = &self.2 as *const SharedMem as *mut SharedMem;
let this = unsafe { &mut *this };
let _ = this.set(index, state);
}
pub fn wait_event(&self, index: usize, timeout: Timeout) {
let this = &self.2 as *const SharedMem as *mut SharedMem;
let this = unsafe { &mut *this };
let _ = this.wait(index, timeout);
}
}
impl Deref for SyncSharedMem {
type Target = [Volatile<u8>];
fn deref(&self) -> &[Volatile<u8>] {
unsafe { slice::from_raw_parts(self.0, self.1) }
}
}
unsafe impl Sync for SyncSharedMem {}
unsafe impl StableAddress for SyncSharedMem {}
pub struct Volatile<T>(UnsafeCell<T>);
impl<T: SharedMemCast> Volatile<T> {
pub fn new(value: T) -> Volatile<T> {
Volatile(UnsafeCell::new(value))
}
pub fn zeroed() -> Volatile<T> {
unsafe { mem::zeroed() }
}
pub fn from_volatile_bytes(bytes: &[Volatile<u8>]) -> Option<&Volatile<T>> {
unsafe {
if mem::size_of::<T>() <= bytes.len() {
(bytes.as_ptr() as *const Volatile<T>).as_ref()
} else {
None
}
}
}
pub fn slice_from_volatile_bytes(
bytes: &[Volatile<u8>],
length: usize,
) -> Option<&[Volatile<T>]> {
unsafe {
if mem::size_of::<T>() * length <= bytes.len() {
let ptr = bytes.as_ptr() as *const Volatile<T>;
Some(slice::from_raw_parts(ptr, length))
} else {
None
}
}
}
pub fn as_ptr(&self) -> *mut T {
self.0.get()
}
pub fn read_volatile(&self) -> T {
unsafe { self.as_ptr().read_volatile() }
}
pub fn write_volatile(&self, value: T) {
unsafe {
self.as_ptr().write_volatile(value);
}
}
}
impl<T: SharedMemCast + SharedMemRef> Deref for Volatile<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.as_ptr() }
}
}
pub fn slice_from_volatile<T: SharedMemCast + SharedMemRef>(slice: &[Volatile<T>]) -> &[T] {
unsafe { mem::transmute(slice) }
}
pub(crate) fn slice_empty<'a, T: 'a>() -> &'a [T] {
unsafe { slice::from_raw_parts(ptr::NonNull::dangling().as_ptr(), 0) }
}
impl From<u64> for SharedAddress {
fn from(data: u64) -> SharedAddress {
unsafe { mem::transmute(data) }
}
}
impl From<SharedAddress> for u64 {
fn from(address: SharedAddress) -> u64 {
unsafe { mem::transmute(address) }
}
}
impl From<u64> for SharedAddressRange {
fn from(data: u64) -> SharedAddressRange {
unsafe { mem::transmute(data) }
}
}
impl From<SharedAddressRange> for u64 {
fn from(address: SharedAddressRange) -> u64 {
unsafe { mem::transmute(address) }
}
}