| 1 | //! Just like [`Cell`] but with [volatile] read / write operations |
| 2 | //! |
| 3 | //! [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html |
| 4 | //! [volatile]: https://doc.rust-lang.org/std/ptr/fn.read_volatile.html |
| 5 | |
| 6 | #![deny (missing_docs)] |
| 7 | #![deny (warnings)] |
| 8 | #![no_std ] |
| 9 | |
| 10 | use core::cell::UnsafeCell; |
| 11 | use core::ptr; |
| 12 | |
| 13 | /// Just like [`Cell`] but with [volatile] read / write operations |
| 14 | /// |
| 15 | /// [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html |
| 16 | /// [volatile]: https://doc.rust-lang.org/std/ptr/fn.read_volatile.html |
| 17 | #[repr (transparent)] |
| 18 | pub struct VolatileCell<T> { |
| 19 | value: UnsafeCell<T>, |
| 20 | } |
| 21 | |
| 22 | impl<T> VolatileCell<T> { |
| 23 | /// Creates a new `VolatileCell` containing the given value |
| 24 | pub const fn new(value: T) -> Self { |
| 25 | VolatileCell { value: UnsafeCell::new(value) } |
| 26 | } |
| 27 | |
| 28 | /// Returns a copy of the contained value |
| 29 | #[inline (always)] |
| 30 | pub fn get(&self) -> T |
| 31 | where T: Copy |
| 32 | { |
| 33 | unsafe { ptr::read_volatile(self.value.get()) } |
| 34 | } |
| 35 | |
| 36 | /// Sets the contained value |
| 37 | #[inline (always)] |
| 38 | pub fn set(&self, value: T) |
| 39 | where T: Copy |
| 40 | { |
| 41 | unsafe { ptr::write_volatile(self.value.get(), value) } |
| 42 | } |
| 43 | |
| 44 | /// Returns a raw pointer to the underlying data in the cell |
| 45 | #[inline (always)] |
| 46 | pub fn as_ptr(&self) -> *mut T { |
| 47 | self.value.get() |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | // NOTE implicit because of `UnsafeCell` |
| 52 | // unsafe impl<T> !Sync for VolatileCell<T> {} |
| 53 | |