On Tue Aug 5, 2025 at 12:47 AM JST, Daniel Almeida wrote: <snip> >> +/// [`align_down!`] macros. >> +/// >> +/// Heavily inspired by the [`Alignment`] nightly feature from the Rust >> standard library, and >> +/// hopefully to be eventually replaced by it. > > It’s a bit hard to parse this. > > Also, I wonder if we should standardize some syntax for TODOs so we can parse > them using a script? This way we can actually keep track and perhaps pipe them > to our GitHub page as “good first issues” or just regular issues. > > I guess a simple "// TODO: “ here will do, for example.
FWIW, in Nova we tag each TODO items with a 4-letter identifier (i.e. `TODO[ABCD]:` that is defined in our `todo.rst` file. This makes grepping all the sites relevant to a given item easy. > >> +/// >> +/// [`Alignment`]: https://github.com/rust-lang/rust/issues/102070 >> +/// >> +/// # Invariants >> +/// >> +/// An alignment is always a power of two. >> +#[repr(transparent)] >> +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] >> +pub struct Alignment(NonZero<usize>); >> + >> +impl Alignment { >> + /// Validates that `align` is a power of two at build-time, and returns >> an [`Alignment`] of the >> + /// same value. >> + /// >> + /// A build error is triggered if `align` cannot be asserted to be a >> power of two. >> + /// >> + /// # Examples >> + /// >> + /// ``` >> + /// use kernel::ptr::Alignment; >> + /// >> + /// let v = Alignment::new(16); >> + /// assert_eq!(v.as_usize(), 16); >> + /// ``` >> + #[inline(always)] >> + pub const fn new(align: usize) -> Self { >> + build_assert!(align.is_power_of_two()); >> + >> + // INVARIANT: `align` is a power of two. >> + // SAFETY: `align` is a power of two, and thus non-zero. >> + Self(unsafe { NonZero::new_unchecked(align) }) >> + } >> + >> + /// Validates that `align` is a power of two at runtime, and returns an >> + /// [`Alignment`] of the same value. >> + /// >> + /// [`None`] is returned if `align` was not a power of two. >> + /// >> + /// # Examples >> + /// >> + /// ``` >> + /// use kernel::ptr::Alignment; >> + /// >> + /// assert_eq!(Alignment::new_checked(16), Some(Alignment::new(16))); >> + /// assert_eq!(Alignment::new_checked(15), None); >> + /// assert_eq!(Alignment::new_checked(1), Some(Alignment::new(1))); >> + /// assert_eq!(Alignment::new_checked(0), None); >> + /// ``` >> + #[inline(always)] >> + pub const fn new_checked(align: usize) -> Option<Self> { >> + if align.is_power_of_two() { >> + // INVARIANT: `align` is a power of two. >> + // SAFETY: `align` is a power of two, and thus non-zero. >> + Some(Self(unsafe { NonZero::new_unchecked(align) })) >> + } else { >> + None >> + } >> + } >> + >> + /// Returns the alignment of `T`. >> + #[inline(always)] >> + pub const fn of<T>() -> Self { >> + // INVARIANT: `align_of` always returns a power of 2. >> + Self(unsafe { NonZero::new_unchecked(align_of::<T>()) }) >> + } > >> + >> + /// Returns the base-2 logarithm of the alignment. >> + /// >> + /// # Examples >> + /// >> + /// ``` >> + /// use kernel::ptr::Alignment; >> + /// >> + /// assert_eq!(Alignment::of::<u8>().log2(), 0); >> + /// assert_eq!(Alignment::new(16).log2(), 4); >> + /// ``` >> + #[inline(always)] >> + pub const fn log2(self) -> u32 { >> + self.0.ilog2() >> + } >> + >> + /// Returns this alignment as a [`NonZero`]. >> + /// >> + /// It is guaranteed to be a power of two. >> + /// >> + /// # Examples >> + /// >> + /// ``` >> + /// use kernel::ptr::Alignment; >> + /// >> + /// assert_eq!(Alignment::new(16).as_nonzero().get(), 16); >> + /// ``` >> + #[inline(always)] >> + pub const fn as_nonzero(self) -> NonZero<usize> { >> + if !self.0.is_power_of_two() { >> + // SAFETY: per the invariants, `self.0` is always a power of >> two so this block will >> + // never be reached. >> + unsafe { core::hint::unreachable_unchecked() } >> + } >> + self.0 >> + } >> + >> + /// Returns this alignment as a `usize`. >> + /// >> + /// It is guaranteed to be a power of two. >> + /// >> + /// # Examples >> + /// >> + /// ``` >> + /// use kernel::ptr::Alignment; >> + /// >> + /// assert_eq!(Alignment::new(16).as_usize(), 16); >> + /// ``` >> + #[inline(always)] >> + pub const fn as_usize(self) -> usize { >> + self.as_nonzero().get() >> + } >> + >> + /// Returns the mask corresponding to `self.as_usize() - 1`. >> + /// >> + /// # Examples >> + /// >> + /// ``` >> + /// use kernel::ptr::Alignment; >> + /// >> + /// assert_eq!(Alignment::new(0x10).mask(), 0xf); >> + /// ``` >> + #[inline(always)] >> + pub const fn mask(self) -> usize { >> + // INVARIANT: `self.as_usize()` is guaranteed to be a power of two >> (i.e. non-zero), thus >> + // `1` can safely be substracted from it. >> + self.as_usize() - 1 >> + } >> + >> + /// Aligns `value` down to this alignment. >> + /// >> + /// If the alignment contained in `self` is too large for `T`, then `0` >> is returned, which >> + /// is correct as it is also the result that would have been returned >> if it did. > > I half get this, but still: If it did what? I also stumbled while re-reading this sentence. :) Fixed.
