Next Generation WASM Microkernel Operating System
at main 61 lines 1.8 kB view raw
1// Copyright 2025 Jonas Kruckenberg 2// 3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or 4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or 5// http://opensource.org/licenses/MIT>, at your option. This file may not be 6// copied, modified, or distributed except according to those terms. 7 8use alloc::boxed::Box; 9use core::ptr; 10use core::sync::atomic::{AtomicPtr, Ordering}; 11 12pub(crate) struct AtomicCell<T> { 13 data: AtomicPtr<T>, 14} 15 16// Safety: `AtomicCell` uses atomic swaps, so as long as the data is Send `AtomicCell` is Send 17unsafe impl<T: Send> Send for AtomicCell<T> {} 18// Safety: `AtomicCell` uses atomic swaps, so as long as the data is Send `AtomicCell` is Sync 19unsafe impl<T: Send> Sync for AtomicCell<T> {} 20 21impl<T> AtomicCell<T> { 22 pub(crate) fn new(data: Option<Box<T>>) -> AtomicCell<T> { 23 AtomicCell { 24 data: AtomicPtr::new(to_raw(data)), 25 } 26 } 27 28 pub(crate) fn swap(&self, val: Option<Box<T>>) -> Option<Box<T>> { 29 let old = self.data.swap(to_raw(val), Ordering::AcqRel); 30 from_raw(old) 31 } 32 33 pub(crate) fn set(&self, val: Box<T>) { 34 let _ = self.swap(Some(val)); 35 } 36 37 pub(crate) fn take(&self) -> Option<Box<T>> { 38 self.swap(None) 39 } 40} 41 42fn to_raw<T>(data: Option<Box<T>>) -> *mut T { 43 data.map_or(ptr::null_mut(), Box::into_raw) 44} 45 46fn from_raw<T>(val: *mut T) -> Option<Box<T>> { 47 if val.is_null() { 48 None 49 } else { 50 // Safety: `from_raw` is only called on pointers created using `to_raw` which are correctly 51 // boxed pointers 52 Some(unsafe { Box::from_raw(val) }) 53 } 54} 55 56impl<T> Drop for AtomicCell<T> { 57 fn drop(&mut self) { 58 // Free any data still held by the cell 59 let _ = self.take(); 60 } 61}