// SPDX-License-Identifier: MIT // // Copyright (c) 2018-2019 Andre Richter //! Synchronization primitives. use crate::interface; use core::cell::UnsafeCell; /// A pseudo-lock for teaching purposes. /// /// Used to introduce [interior mutability]. /// /// In contrast to a real Mutex implementation, does not protect against /// concurrent access to the contained data. This part is preserved for later /// lessons. /// /// The lock will only be used as long as it is safe to do so, i.e. as long as /// the kernel is executing single-threaded, aka only running on a single core /// with interrupts disabled. /// /// [interior mutability]: https://doc.rust-lang.org/std/cell/index.html pub struct NullLock { data: UnsafeCell, } unsafe impl Send for NullLock {} unsafe impl Sync for NullLock {} impl NullLock { pub const fn new(data: T) -> NullLock { NullLock { data: UnsafeCell::new(data), } } } impl interface::sync::Mutex for &NullLock { type Data = T; fn lock(&mut self, f: impl FnOnce(&mut Self::Data) -> R) -> R { // In a real lock, there would be code encapsulating this line that // ensures that this mutable reference will ever only be given out once // at a time. f(unsafe { &mut *self.data.get() }) } }