diff --git a/crates/sel4-externally-shared/src/atomics/mod.rs b/crates/sel4-externally-shared/src/atomics/mod.rs index 51d179cd1..a49fe372f 100644 --- a/crates/sel4-externally-shared/src/atomics/mod.rs +++ b/crates/sel4-externally-shared/src/atomics/mod.rs @@ -6,7 +6,9 @@ use core::fmt; use core::marker::PhantomData; +use core::mem; use core::ptr::NonNull; +use core::sync::atomic; use volatile::access::{ReadOnly, ReadWrite, WriteOnly}; @@ -41,6 +43,10 @@ impl fmt::Debug for AtomicPtr<'_, T, A> { } impl<'a, T, A> AtomicPtr<'a, T, A> { + /// # Safety + /// + /// Necessary but not sufficient: + /// * `pointer` must be aligned to `align_of::()` #[allow(clippy::missing_safety_doc)] pub const unsafe fn new(pointer: NonNull) -> Self { AtomicPtr { @@ -65,6 +71,7 @@ impl<'a, T, A> AtomicPtr<'a, T, A> { #[allow(clippy::missing_safety_doc)] pub unsafe trait Atomic: AtomicSealed + Copy { + const ALIGNMENT: usize; const IS_SIGNED: bool; } @@ -75,11 +82,16 @@ mod sealing { } macro_rules! impl_atomic { - ($t:ty, $target_has_atomic_key:literal, $is_signed:literal) => { + ( + $t:ty, + $target_has_atomic_key:literal, + $is_signed:literal, + $analog_for_alignment:path + ) => { // TODO these attributes are overly conservative #[cfg(target_has_atomic = $target_has_atomic_key)] - #[cfg(target_has_atomic_equal_alignment = $target_has_atomic_key)] unsafe impl Atomic for $t { + const ALIGNMENT: usize = mem::align_of::<$analog_for_alignment>(); const IS_SIGNED: bool = $is_signed; } @@ -88,20 +100,35 @@ macro_rules! impl_atomic { } macro_rules! impl_atomic_for_each_signedness { - ($t_unsigned:ty, $t_signed:ty, $target_has_atomic_key:literal) => { - impl_atomic!($t_unsigned, $target_has_atomic_key, false); - impl_atomic!($t_signed, $target_has_atomic_key, true); + ( + $t_unsigned:ty, + $t_signed:ty, + $target_has_atomic_key:literal, + $unsigned_analog_for_alignment:path, + $signed_analog_for_alignment:path + ) => { + impl_atomic!( + $t_unsigned, + $target_has_atomic_key, + false, + $unsigned_analog_for_alignment + ); + impl_atomic!( + $t_signed, + $target_has_atomic_key, + true, + $signed_analog_for_alignment + ); }; } -impl_atomic_for_each_signedness!(u8, i8, "8"); -impl_atomic_for_each_signedness!(u16, i16, "16"); -impl_atomic_for_each_signedness!(u32, i32, "32"); -impl_atomic_for_each_signedness!(u64, i64, "64"); -impl_atomic_for_each_signedness!(u128, i128, "128"); +impl_atomic_for_each_signedness!(u8, i8, "8", atomic::AtomicU8, atomic::AtomicI8); +impl_atomic_for_each_signedness!(u16, i16, "16", atomic::AtomicU16, atomic::AtomicI16); +impl_atomic_for_each_signedness!(u32, i32, "32", atomic::AtomicU32, atomic::AtomicI32); +impl_atomic_for_each_signedness!(u64, i64, "64", atomic::AtomicU64, atomic::AtomicI64); #[cfg(target_pointer_width = "32")] -impl_atomic_for_each_signedness!(usize, isize, "32"); +impl_atomic_for_each_signedness!(usize, isize, "32", atomic::AtomicUsize, atomic::AtomicIsize); #[cfg(target_pointer_width = "64")] -impl_atomic_for_each_signedness!(usize, isize, "64"); +impl_atomic_for_each_signedness!(usize, isize, "64", atomic::AtomicUsize, atomic::AtomicIsize); diff --git a/crates/sel4-externally-shared/src/lib.rs b/crates/sel4-externally-shared/src/lib.rs index d56d07095..38866b6d5 100644 --- a/crates/sel4-externally-shared/src/lib.rs +++ b/crates/sel4-externally-shared/src/lib.rs @@ -5,7 +5,6 @@ // #![no_std] -#![feature(cfg_target_has_atomic_equal_alignment)] #![feature(core_intrinsics)] #![allow(internal_features)] @@ -55,6 +54,8 @@ impl<'a, T: ?Sized, A> ExternallySharedPtrExt<'a, T, A> for ExternallySharedPtr< where T: Atomic, { - unsafe { AtomicPtr::new(self.as_raw_ptr()) } + let p = self.as_raw_ptr(); + assert_eq!(p.as_ptr().align_offset(T::ALIGNMENT), 0); + unsafe { AtomicPtr::new(p) } } }