From 4083e955d4fbfc4b95872728e23fc8ce4249792d Mon Sep 17 00:00:00 2001 From: Berkus Decker Date: Sat, 17 Oct 2020 20:58:49 +0300 Subject: [PATCH] Add dummy synchronisation primitive It is used yet on single-core single-thread system. Once more threads and more cores are active, better synchronisation primitives will be introduced. --- nucleus/src/main.rs | 1 + nucleus/src/sync.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 nucleus/src/sync.rs diff --git a/nucleus/src/main.rs b/nucleus/src/main.rs index 9f5feb0..a2ba8e0 100644 --- a/nucleus/src/main.rs +++ b/nucleus/src/main.rs @@ -32,6 +32,7 @@ mod macros; mod platform; #[cfg(feature = "qemu")] mod qemu; +mod sync; #[cfg(test)] mod tests; mod write_to; diff --git a/nucleus/src/sync.rs b/nucleus/src/sync.rs new file mode 100644 index 0000000..9983b59 --- /dev/null +++ b/nucleus/src/sync.rs @@ -0,0 +1,44 @@ +/* + * SPDX-License-Identifier: MIT OR BlueOak-1.0.0 + * Copyright (c) 2019 Andre Richter + * Original code distributed under MIT, additional changes are under BlueOak-1.0.0 + */ + +use core::cell::UnsafeCell; + +pub struct NullLock { + data: UnsafeCell, +} + +/// Since we are instantiating this struct as a static variable, which could +/// potentially be shared between different threads, we need to tell the compiler +/// that sharing of this struct is safe by marking it with the Sync trait. +/// +/// At this point in time, we can do so without worrying, because the kernel +/// anyways runs on a single core and interrupts are disabled. In short, multiple +/// threads don't exist yet in our code. +/// +/// Literature: +/// https://doc.rust-lang.org/beta/nomicon/send-and-sync.html +/// https://doc.rust-lang.org/book/ch16-04-extensible-concurrency-sync-and-send.html +unsafe impl Sync for NullLock {} + +impl NullLock { + pub const fn new(data: T) -> NullLock { + NullLock { + data: UnsafeCell::new(data), + } + } +} + +impl NullLock { + pub fn lock(&self, f: F) -> R + where + F: FnOnce(&mut T) -> R, + { + // In a real lock, there would be code around this line that ensures + // that this mutable reference will ever only be given out to one thread + // at a time. + f(unsafe { &mut *self.data.get() }) + } +}