sel4_immediate_sync_once_cell/
lib.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: BSD-2-Clause
5//
6
7#![no_std]
8
9use core::cell::UnsafeCell;
10use core::sync::atomic::{AtomicBool, Ordering};
11
12pub struct ImmediateSyncOnceCell<T> {
13    init_started: AtomicBool,
14    init_completed: AtomicBool,
15    inner: UnsafeCell<Option<T>>,
16}
17
18unsafe impl<T> Sync for ImmediateSyncOnceCell<T> {}
19
20impl<T> Default for ImmediateSyncOnceCell<T> {
21    fn default() -> Self {
22        Self::new()
23    }
24}
25
26impl<T> ImmediateSyncOnceCell<T> {
27    pub const fn new() -> Self {
28        Self {
29            init_started: AtomicBool::new(false),
30            init_completed: AtomicBool::new(false),
31            inner: UnsafeCell::new(None),
32        }
33    }
34
35    pub fn get(&self) -> Option<&T> {
36        if self.init_completed.load(Ordering::Acquire) {
37            Some(unsafe { self.inner.get().as_ref().unwrap().as_ref().unwrap() })
38        } else {
39            None
40        }
41    }
42
43    pub fn set(&self, value: T) -> Result<(), T> {
44        if self.init_started.swap(true, Ordering::SeqCst) {
45            Err(value)
46        } else {
47            unsafe {
48                *self.inner.get().as_mut().unwrap() = Some(value);
49            }
50            self.init_completed.store(true, Ordering::SeqCst);
51            Ok(())
52        }
53    }
54}