From f2926f5f255c9fab40efec7abc05bda8684842f7 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Mon, 5 Jul 2021 11:27:22 +0200 Subject: [PATCH] Pre-initialize the context list at compile time. --- src/context/list.rs | 2 +- src/context/mod.rs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/context/list.rs b/src/context/list.rs index 90dd566..6182697 100644 --- a/src/context/list.rs +++ b/src/context/list.rs @@ -18,7 +18,7 @@ pub struct ContextList { impl ContextList { /// Create a new context list. - pub fn new() -> Self { + pub const fn new() -> Self { ContextList { map: BTreeMap::new(), next_id: 1 diff --git a/src/context/mod.rs b/src/context/mod.rs index 6fe66b6..9268b14 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -48,7 +48,7 @@ pub const CONTEXT_MAX_CONTEXTS: usize = (isize::max_value() as usize) - 1; pub const CONTEXT_MAX_FILES: usize = 65_536; /// Contexts list -static CONTEXTS: Once> = Once::new(); +static CONTEXTS: RwLock = RwLock::new(ContextList::new()); #[thread_local] static CONTEXT_ID: context::AtomicContextId = context::AtomicContextId::default(); @@ -77,16 +77,20 @@ fn init_contexts() -> RwLock { /// Get the global schemes list, const pub fn contexts() -> RwLockReadGuard<'static, ContextList> { - //call once will init_contexts only once during the kernel's exececution, otherwise it will return the current context via a - //cache. - CONTEXTS.call_once(init_contexts).read() + CONTEXTS.read() } /// Get the global schemes list, mutable pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> { - CONTEXTS.call_once(init_contexts).write() + CONTEXTS.write() } pub fn context_id() -> ContextId { - CONTEXT_ID.load(Ordering::SeqCst) + // Thread local variables can and should only be modified using Relaxed. This is to prevent a + // hardware thread from racing with itself, for example if there is an interrupt. Orderings + // stronger than Relaxed are only necessary for inter-processor synchronization. + let id = CONTEXT_ID.load(Ordering::Relaxed); + // Prevent the compiler from reordering subsequent loads and stores to before this load. + core::sync::atomic::compiler_fence(Ordering::Acquire); + id }