1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use crate::lib::std::cell::Cell;
use crate::lib::std::marker::PhantomData;
use crate::lib::std::ops::Deref;
use crate::lib::std::slice;
use crate::lib::std::sync::atomic::{
AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicU16, AtomicU32, AtomicU64, AtomicU8,
};
use crate::native::ValueType;
pub trait Atomic {
type Output;
}
macro_rules! atomic {
( $($for:ty => $output:ty),+ ) => {
$(
impl Atomic for $for {
type Output = $output;
}
)+
}
}
atomic!(
i8 => AtomicI8,
i16 => AtomicI16,
i32 => AtomicI32,
i64 => AtomicI64,
u8 => AtomicU8,
u16 => AtomicU16,
u32 => AtomicU32,
u64 => AtomicU64,
f32 => AtomicU32,
f64 => AtomicU64
);
pub trait Atomicity {}
pub struct Atomically;
impl Atomicity for Atomically {}
pub struct NonAtomically;
impl Atomicity for NonAtomically {}
pub struct MemoryView<'a, T: 'a, A = NonAtomically> {
ptr: *mut T,
length: usize,
_phantom: PhantomData<(&'a [Cell<T>], A)>,
}
impl<'a, T> MemoryView<'a, T, NonAtomically>
where
T: ValueType,
{
pub unsafe fn new(ptr: *mut T, length: u32) -> Self {
Self {
ptr,
length: length as usize,
_phantom: PhantomData,
}
}
pub fn subarray(&self, start: u32, end: u32) -> Self {
assert!(
(start as usize) < self.length,
"The range start is bigger than current length"
);
assert!(
(end as usize) < self.length,
"The range end is bigger than current length"
);
Self {
ptr: unsafe { self.ptr.add(start as usize) },
length: (end - start) as usize,
_phantom: PhantomData,
}
}
pub unsafe fn copy_from(&self, src: &[T]) {
let sliced_src = &src[..self.length];
for (i, byte) in sliced_src.iter().enumerate() {
*self.ptr.offset(i as isize) = *byte;
}
}
}
impl<'a, T: Atomic> MemoryView<'a, T> {
pub fn atomically(&self) -> MemoryView<'a, T::Output, Atomically> {
MemoryView {
ptr: self.ptr as *mut T::Output,
length: self.length,
_phantom: PhantomData,
}
}
}
impl<'a, T> Deref for MemoryView<'a, T, NonAtomically> {
type Target = [Cell<T>];
fn deref(&self) -> &[Cell<T>] {
let mut_slice: &mut [T] = unsafe { slice::from_raw_parts_mut(self.ptr, self.length) };
let cell_slice: &Cell<[T]> = Cell::from_mut(mut_slice);
cell_slice.as_slice_of_cells()
}
}
impl<'a, T> Deref for MemoryView<'a, T, Atomically> {
type Target = [T];
fn deref(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.ptr as *const T, self.length) }
}
}