sel4_one_ref_cell/
lib.rs
1#![no_std]
8
9use core::cell::UnsafeCell;
10use core::sync::atomic::{AtomicBool, Ordering};
11
12pub struct OneRefCell<T> {
13 taken: AtomicBool,
14 value: UnsafeCell<T>,
15}
16
17unsafe impl<T> Sync for OneRefCell<T> {}
18
19impl<T: Default> Default for OneRefCell<T> {
20 fn default() -> Self {
21 Self::new(Default::default())
22 }
23}
24
25impl<T> From<T> for OneRefCell<T> {
26 fn from(t: T) -> Self {
27 Self::new(t)
28 }
29}
30
31impl<T> OneRefCell<T> {
32 pub const fn new(value: T) -> Self {
33 Self {
34 taken: AtomicBool::new(false),
35 value: UnsafeCell::new(value),
36 }
37 }
38
39 pub fn take(&self) -> Result<&mut T, Error> {
40 if self.taken.swap(true, Ordering::SeqCst) {
41 Err(Error::AlreadyTaken)
42 } else {
43 let ptr = self.value.get();
44 Ok(unsafe { ptr.as_mut() }.unwrap())
45 }
46 }
47}
48
49#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
50pub enum Error {
51 AlreadyTaken,
52}