Created
July 23, 2020 03:37
-
-
Save unpluggedcoder/10106a82d7b72850d95de603d10aedc9 to your computer and use it in GitHub Desktop.
Simple SpinLock written by Rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/koute/memory-profiler/blob/master/preload/src/spin_lock.rs | |
use std::sync::atomic::{AtomicBool, Ordering}; | |
use std::ops::{Deref, DerefMut}; | |
use std::cell::UnsafeCell; | |
use std::mem::transmute; | |
pub struct SpinLock< T > { | |
pub value: UnsafeCell< T >, | |
pub flag: AtomicBool | |
} | |
unsafe impl< T > Send for SpinLock< T > {} | |
unsafe impl< T > Sync for SpinLock< T > {} | |
pub struct SpinLockGuard< 'a, T: 'a >( &'a SpinLock< T > ); | |
impl< T > SpinLock< T > { | |
pub const fn new( value: T ) -> Self { | |
SpinLock { | |
value: UnsafeCell::new( value ), | |
flag: AtomicBool::new( false ) | |
} | |
} | |
pub fn lock( &self ) -> SpinLockGuard< T > { | |
while self.flag.compare_and_swap( false, true, Ordering::Acquire ) != false { | |
} | |
SpinLockGuard( self ) | |
} | |
pub fn try_lock( &self ) -> Option< SpinLockGuard< T > > { | |
if self.flag.compare_and_swap( false, true, Ordering::Acquire ) == false { | |
Some( SpinLockGuard( self ) ) | |
} else { | |
None | |
} | |
} | |
pub unsafe fn unsafe_as_ref( &self ) -> &T { | |
&*self.value.get() | |
} | |
pub unsafe fn force_unlock( &self ) { | |
self.flag.store( false, Ordering::SeqCst ); | |
} | |
} | |
impl< 'a, T > SpinLockGuard< 'a, T > { | |
#[allow(dead_code)] | |
pub fn unwrap( self ) -> Self { | |
self | |
} | |
} | |
impl< 'a, T > SpinLockGuard< 'a, *mut T > { | |
#[allow(dead_code)] | |
pub unsafe fn as_ref( self ) -> SpinLockGuard< 'a, &'a T > { | |
transmute( self ) | |
} | |
} | |
impl< 'a, T > Drop for SpinLockGuard< 'a, T > { | |
fn drop( &mut self ) { | |
self.0.flag.store( false, Ordering::Release ); | |
} | |
} | |
impl< 'a, T > Deref for SpinLockGuard< 'a, T > { | |
type Target = T; | |
fn deref( &self ) -> &Self::Target { | |
unsafe { | |
transmute( self.0.value.get() ) | |
} | |
} | |
} | |
impl< 'a, T > DerefMut for SpinLockGuard< 'a, T > { | |
fn deref_mut( &mut self ) -> &mut Self::Target { | |
unsafe { | |
transmute( self.0.value.get() ) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment