From c5996b80beaba54502fa86583b48cd6980b17b18 Mon Sep 17 00:00:00 2001 From: John Kåre Alsaker Date: Thu, 31 Aug 2023 12:50:44 +0200 Subject: Use `Freeze` for `SourceFile.external_src` --- compiler/rustc_data_structures/src/sync/freeze.rs | 47 +++++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_data_structures/src/sync') diff --git a/compiler/rustc_data_structures/src/sync/freeze.rs b/compiler/rustc_data_structures/src/sync/freeze.rs index d9f1d72d851..88c710e5236 100644 --- a/compiler/rustc_data_structures/src/sync/freeze.rs +++ b/compiler/rustc_data_structures/src/sync/freeze.rs @@ -27,7 +27,26 @@ unsafe impl DynSync for FreezeLock {} impl FreezeLock { #[inline] pub fn new(value: T) -> Self { - Self { data: UnsafeCell::new(value), frozen: AtomicBool::new(false), lock: RwLock::new(()) } + Self::with(value, false) + } + + #[inline] + pub fn frozen(value: T) -> Self { + Self::with(value, true) + } + + #[inline] + pub fn with(value: T, frozen: bool) -> Self { + Self { + data: UnsafeCell::new(value), + frozen: AtomicBool::new(frozen), + lock: RwLock::new(()), + } + } + + #[inline] + pub fn is_frozen(&self) -> bool { + self.frozen.load(Ordering::Acquire) } #[inline] @@ -42,13 +61,26 @@ impl FreezeLock { } } + #[inline] + pub fn borrow(&self) -> FreezeReadGuard<'_, T> { + self.read() + } + #[inline] #[track_caller] pub fn write(&self) -> FreezeWriteGuard<'_, T> { + self.try_write().expect("still mutable") + } + + #[inline] + pub fn try_write(&self) -> Option> { let _lock_guard = self.lock.write(); // Use relaxed ordering since we're in the write lock. - assert!(!self.frozen.load(Ordering::Relaxed), "still mutable"); - FreezeWriteGuard { _lock_guard, lock: self, marker: PhantomData } + if self.frozen.load(Ordering::Relaxed) { + None + } else { + Some(FreezeWriteGuard { _lock_guard, lock: self, marker: PhantomData }) + } } #[inline] @@ -90,6 +122,15 @@ pub struct FreezeWriteGuard<'a, T> { marker: PhantomData<&'a mut T>, } +impl<'a, T> FreezeWriteGuard<'a, T> { + pub fn freeze(self) -> &'a T { + self.lock.frozen.store(true, Ordering::Release); + + // SAFETY: This is frozen so the data cannot be modified and shared access is sound. + unsafe { &*self.lock.data.get() } + } +} + impl<'a, T: 'a> Deref for FreezeWriteGuard<'a, T> { type Target = T; #[inline] -- cgit 1.4.1-3-g733a5