diff --git a/src/data.rs b/src/data.rs index 7b640b737c..58c5c56072 100644 --- a/src/data.rs +++ b/src/data.rs @@ -1,6 +1,9 @@ -use core::ops::{Deref, DerefMut}; -use core::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; -use core::{mem, slice}; +use core::{ + mem, + ops::{Deref, DerefMut}, + slice, + sync::atomic::{AtomicUsize, Ordering}, +}; use crate::flag::{EventFlags, MapFlags, PtraceFlags, SigcontrolFlags}; @@ -9,23 +12,19 @@ use crate::flag::{EventFlags, MapFlags, PtraceFlags, SigcontrolFlags}; pub struct Event { pub id: usize, pub flags: EventFlags, - pub data: usize + pub data: usize, } impl Deref for Event { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::()) - } + unsafe { slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::()) } } } impl DerefMut for Event { fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::()) - } + unsafe { slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::()) } } } @@ -40,8 +39,10 @@ impl Deref for ITimerSpec { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const ITimerSpec as *const u8, - mem::size_of::()) + slice::from_raw_parts( + self as *const ITimerSpec as *const u8, + mem::size_of::(), + ) } } } @@ -49,8 +50,10 @@ impl Deref for ITimerSpec { impl DerefMut for ITimerSpec { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut ITimerSpec as *mut u8, - mem::size_of::()) + slice::from_raw_parts_mut( + self as *mut ITimerSpec as *mut u8, + mem::size_of::(), + ) } } } @@ -100,17 +103,13 @@ pub struct Map { impl Deref for Map { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts(self as *const Map as *const u8, mem::size_of::()) - } + unsafe { slice::from_raw_parts(self as *const Map as *const u8, mem::size_of::()) } } } impl DerefMut for Map { fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut(self as *mut Map as *mut u8, mem::size_of::()) - } + unsafe { slice::from_raw_parts_mut(self as *mut Map as *mut u8, mem::size_of::()) } } } @@ -124,7 +123,7 @@ pub struct Packet { pub a: usize, pub b: usize, pub c: usize, - pub d: usize + pub d: usize, } impl Deref for Packet { @@ -167,19 +166,13 @@ pub struct Stat { impl Deref for Stat { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts(self as *const Stat as *const u8, - mem::size_of::()) - } + unsafe { slice::from_raw_parts(self as *const Stat as *const u8, mem::size_of::()) } } } impl DerefMut for Stat { fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut(self as *mut Stat as *mut u8, - mem::size_of::()) - } + unsafe { slice::from_raw_parts_mut(self as *mut Stat as *mut u8, mem::size_of::()) } } } @@ -196,8 +189,10 @@ impl Deref for StatVfs { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const StatVfs as *const u8, - mem::size_of::()) + slice::from_raw_parts( + self as *const StatVfs as *const u8, + mem::size_of::(), + ) } } } @@ -205,8 +200,7 @@ impl Deref for StatVfs { impl DerefMut for StatVfs { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut StatVfs as *mut u8, - mem::size_of::()) + slice::from_raw_parts_mut(self as *mut StatVfs as *mut u8, mem::size_of::()) } } } @@ -222,8 +216,10 @@ impl Deref for TimeSpec { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const TimeSpec as *const u8, - mem::size_of::()) + slice::from_raw_parts( + self as *const TimeSpec as *const u8, + mem::size_of::(), + ) } } } @@ -231,8 +227,7 @@ impl Deref for TimeSpec { impl DerefMut for TimeSpec { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8, - mem::size_of::()) + slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8, mem::size_of::()) } } } @@ -246,14 +241,17 @@ pub struct PtraceEvent { pub c: usize, pub d: usize, pub e: usize, - pub f: usize + pub f: usize, } impl Deref for PtraceEvent { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const PtraceEvent as *const u8, mem::size_of::()) + slice::from_raw_parts( + self as *const PtraceEvent as *const u8, + mem::size_of::(), + ) } } } @@ -261,7 +259,10 @@ impl Deref for PtraceEvent { impl DerefMut for PtraceEvent { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut PtraceEvent as *mut u8, mem::size_of::()) + slice::from_raw_parts_mut( + self as *mut PtraceEvent as *mut u8, + mem::size_of::(), + ) } } } @@ -317,7 +318,10 @@ impl Deref for GrantDesc { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const GrantDesc as *const u8, mem::size_of::()) + slice::from_raw_parts( + self as *const GrantDesc as *const u8, + mem::size_of::(), + ) } } } @@ -325,7 +329,10 @@ impl Deref for GrantDesc { impl DerefMut for GrantDesc { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut GrantDesc as *mut u8, mem::size_of::()) + slice::from_raw_parts_mut( + self as *mut GrantDesc as *mut u8, + mem::size_of::(), + ) } } } @@ -342,17 +349,13 @@ pub struct SetSighandlerData { impl Deref for SetSighandlerData { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { - slice::from_raw_parts(self as *const Self as *const u8, mem::size_of::()) - } + unsafe { slice::from_raw_parts(self as *const Self as *const u8, mem::size_of::()) } } } impl DerefMut for SetSighandlerData { fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut(self as *mut Self as *mut u8, mem::size_of::()) - } + unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut u8, mem::size_of::()) } } } /// Signal runtime struct for the entire process @@ -432,3 +435,96 @@ impl SigProcControl { self.word[0].load(Ordering::SeqCst) & bit == bit } } + +#[cfg(target_has_atomic = "64")] +pub use core::sync::atomic::AtomicU64; + +#[cfg(target_arch = "x86")] +pub use self::atomic::AtomicU64; + +#[cfg(target_arch = "x86")] +mod atomic { + use core::{cell::UnsafeCell, sync::atomic::Ordering}; + + #[derive(Debug, Default)] + pub struct AtomicU64(UnsafeCell); + + unsafe impl Send for AtomicU64 {} + unsafe impl Sync for AtomicU64 {} + + impl AtomicU64 { + pub const fn new(inner: u64) -> Self { + Self(UnsafeCell::new(inner)) + } + pub fn compare_exchange( + &self, + old: u64, + new: u64, + _success: Ordering, + _failure: Ordering, + ) -> Result { + let old_hi = (old >> 32) as u32; + let old_lo = old as u32; + let new_hi = (new >> 32) as u32; + let new_lo = new as u32; + let mut out_hi; + let mut out_lo; + + unsafe { + core::arch::asm!("cmpxchg8b [{}]", in(reg) self.0.get(), inout("eax") old_hi => out_hi, inout("edx") old_lo => out_lo, in("ecx") new_hi, in("ebx") new_lo); + } + + if old_hi == out_hi && old_lo == out_lo { + Ok(old) + } else { + Ok(u64::from(out_lo) | (u64::from(out_hi) << 32)) + } + } + pub fn load(&self, ordering: Ordering) -> u64 { + match self.compare_exchange(0, 0, ordering, ordering) { + Ok(new) => new, + Err(new) => new, + } + } + pub fn store(&self, new: u64, ordering: Ordering) { + let mut old = 0; + + loop { + match self.compare_exchange(old, new, ordering, Ordering::Relaxed) { + Ok(_) => break, + Err(new) => { + old = new; + core::hint::spin_loop(); + } + } + } + } + pub fn fetch_update( + &self, + set_order: Ordering, + fetch_order: Ordering, + mut f: impl FnMut(u64) -> Option, + ) -> Result { + let mut old = self.load(fetch_order); + + loop { + let new = f(old).ok_or(old)?; + match self.compare_exchange(old, new, set_order, Ordering::Relaxed) { + Ok(_) => return Ok(new), + Err(changed) => { + old = changed; + core::hint::spin_loop(); + } + } + } + } + pub fn fetch_or(&self, bits: u64, order: Ordering) -> u64 { + self.fetch_update(order, Ordering::Relaxed, |b| Some(b | bits)) + .unwrap() + } + pub fn fetch_and(&self, bits: u64, order: Ordering) -> u64 { + self.fetch_update(order, Ordering::Relaxed, |b| Some(b & bits)) + .unwrap() + } + } +}