1#![no_std]
2use core::fmt;
3use core::mem::MaybeUninit;
4use core::ops::Deref;
5use core::ptr;
6use core::sync::atomic::Ordering::{Relaxed, SeqCst};
7use interrupt::CriticalSection;
8use util::*;
9
10pub struct Ref<'a, T>(&'a Cell<T>);
11impl<'a, T> Ref<'a, T> {
12 pub fn ref_num(&self) -> Result<usize, MemoryState> {
13 self.0.ref_num()
14 }
15 pub fn remove(&self) {
17 let _ = self.0.state.fetch_update(SeqCst, Relaxed, |mut x| {
18 x.set_state(MemoryState::Erasing);
19 Some(x)
20 });
21 }
22 pub fn will_remove(&self) -> bool {
23 self.0.state.load(SeqCst).state().is_erasing()
24 }
25}
26impl<'a, T> Deref for Ref<'a, T> {
27 type Target = T;
28 fn deref(&self) -> &Self::Target {
29 unsafe { self.0.val.assume_init_ref() }
30 }
31}
32impl<'a, T: fmt::Debug> fmt::Debug for Ref<'a, T> {
33 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
34 let v: &T = self;
35 fmt::Debug::fmt(&v, f)
36 }
37}
38impl<'a, T> Drop for Ref<'a, T> {
39 fn drop(&mut self) {
40 let _cs = CriticalSection::new();
41 let old = match self.0.state.fetch_update(SeqCst, Relaxed, |mut x| {
42 if x.ref_sub().is_ok() {
43 Some(x)
44 } else {
45 None
46 }
47 }) {
48 Ok(v) => v,
49 Err(v) => v,
50 };
51 let will_drop = self.will_remove();
52 if old.ref_num() == Ok(1) && will_drop {
53 unsafe { ptr::drop_in_place(self.0.val.as_ptr() as *mut T) };
54 self.0
55 .state
56 .store(MemoryState::Uninitialized.into(), SeqCst);
57 }
58 }
59}
60
61pub struct Cell<T> {
62 val: MaybeUninit<T>,
63 state: AtomicMemoryRefer,
64}
65impl<T> Default for Cell<T> {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70impl<T> Cell<T> {
71 pub const fn new() -> Self {
72 Cell {
73 val: MaybeUninit::uninit(),
74 state: AtomicMemoryRefer::new(MemoryRefer::new()),
75 }
76 }
77 pub const fn new_with(init: T) -> Self {
78 Cell {
79 val: MaybeUninit::new(init),
80 state: AtomicMemoryRefer::new(MemoryRefer::new()),
81 }
82 }
83 fn ptr(&self) -> *mut T {
84 self.val.as_ptr() as *mut T
85 }
86 pub fn is_initialized(&self) -> bool {
87 let state = self.state.load(SeqCst);
88 state.state().is_initialized()
89 }
90 pub fn ref_num(&self) -> Result<usize, MemoryState> {
91 self.state.load(SeqCst).ref_num()
92 }
93
94 pub fn try_take(&self) -> Result<Option<T>, Error<()>> {
98 let _cs = CriticalSection::new();
99 let refer = match self.state.fetch_update(SeqCst, Relaxed, |mut x| {
100 let state = x.state();
101 if state.is_initialized() || state.is_regaining() {
102 if x.ref_num() == Ok(0) {
103 x.set_state(MemoryState::Erasing);
104 } else {
105 x.set_state(MemoryState::Regaining);
106 }
107 Some(x)
108 } else {
109 None
110 }
111 }) {
112 Ok(v) => v,
113 Err(v) => v,
114 };
115
116 match refer.state() {
117 MemoryState::Uninitialized => Ok(None),
118 MemoryState::Initialized | MemoryState::Regaining => {
119 if refer.ref_num() == Ok(0) {
120 let ret = unsafe { ptr::read(self.ptr()) };
121 self.state.store(MemoryState::Uninitialized.into(), SeqCst);
122 Ok(Some(ret))
123 } else {
124 Err(Error {
125 state: MemoryState::Regaining,
126 input: (),
127 retry: true,
128 })
129 }
130 }
131 state => Err(Error {
132 state,
133 input: (),
134 retry: state.is_transient(),
135 }),
136 }
137 }
138 pub fn take(&self) -> Result<Option<T>, Error<()>> {
144 retry(|_| self.try_take(), ())
145 }
146
147 pub unsafe fn peek(&self) -> &T {
150 self.val.assume_init_ref()
151 }
152 pub fn try_get(&self) -> Result<Ref<'_, T>, Error<()>> {
156 if let Err(state) = self.state.fetch_update(SeqCst, Relaxed, |mut x| {
157 if x.ref_add().is_ok() {
158 Some(x)
159 } else {
160 None
161 }
162 }) {
163 let state = state.state();
164 Err(Error {
165 state,
166 input: (),
167 retry: state.is_initializing(),
168 })
169 } else {
170 Ok(Ref(self))
171 }
172 }
173 pub fn get(&self) -> Result<Ref<'_, T>, Error<()>> {
179 retry(|_| self.try_get(), ())
180 }
181
182 pub fn try_set(&self, value: T) -> Result<(), Error<T>> {
186 let _cs = CriticalSection::new();
187 if let Err(state) = self.state.compare_exchange(
188 MemoryState::Uninitialized.into(),
189 MemoryState::Initializing.into(),
190 SeqCst,
191 SeqCst,
192 ) {
193 let state = state.state();
194 Err(Error {
195 state,
196 input: value,
197 retry: state.is_erasing(),
198 })
199 } else {
200 unsafe { ptr::write(self.ptr(), value) };
201 self.state.store(MemoryState::Initialized.into(), SeqCst);
202 Ok(())
203 }
204 }
205 pub fn set(&self, value: T) -> Result<(), Error<T>> {
211 retry(|v| self.try_set(v), value)
212 }
213
214 pub fn try_replace(&self, value: T) -> Result<Option<T>, Error<T>> {
218 let _cs = CriticalSection::new();
219 let refer = match self.state.fetch_update(SeqCst, Relaxed, |mut x| {
220 let state = x.state();
221 if state.is_initialized() || state.is_regaining() {
222 if x.ref_num() == Ok(0) {
223 x.set_state(MemoryState::Initializing);
224 } else {
225 x.set_state(MemoryState::Regaining);
226 }
227 Some(x)
228 } else if state.is_uninitialized() {
229 x.set_state(MemoryState::Initializing);
230 Some(x)
231 } else {
232 None
233 }
234 }) {
235 Ok(v) => v,
236 Err(v) => v,
237 };
238
239 match refer.state() {
240 MemoryState::Uninitialized => {
241 unsafe { ptr::write(self.ptr(), value) };
242 self.state.store(MemoryState::Initialized.into(), SeqCst);
243 Ok(None)
244 }
245 MemoryState::Initialized | MemoryState::Regaining => {
246 if refer.ref_num() == Ok(0) {
247 let ret = unsafe { ptr::read(self.ptr()) };
248 unsafe { ptr::write(self.ptr(), value) };
249 self.state.store(MemoryState::Initialized.into(), SeqCst);
250 Ok(Some(ret))
251 } else {
252 Err(Error {
253 state: MemoryState::Regaining,
254 input: value,
255 retry: true,
256 })
257 }
258 }
259 state => Err(Error {
260 state,
261 input: value,
262 retry: state.is_transient(),
263 }),
264 }
265 }
266 pub fn replace(&self, value: T) -> Result<Option<T>, Error<T>> {
272 retry(|v| self.try_replace(v), value)
273 }
274
275 pub fn get_or_try_init(&self, value: T) -> Result<Ref<'_, T>, Error<T>> {
279 let ret = self.try_set(value);
280 if let Ok(v) = self.try_get() {
281 Ok(v)
282 } else {
283 Err(ret.unwrap_err())
284 }
285 }
286 pub fn get_or_init(&self, value: T) -> Ref<'_, T> {
290 retry(|v| self.get_or_try_init(v), value).unwrap()
291 }
292}
293impl<T: fmt::Debug> fmt::Debug for Cell<T> {
294 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
295 let v = self.try_get().ok();
296 fmt::Debug::fmt(&v, f)
297 }
298}
299impl<T> Drop for Cell<T> {
300 fn drop(&mut self) {
301 let _ = self.take();
302 }
303}