rust/kernel/ptr.rs

Source file repositories/reference/linux-study-clean/rust/kernel/ptr.rs

File Facts

System
Linux kernel
Corpus path
rust/kernel/ptr.rs
Extension
.rs
Size
8833 bytes
Lines
284
Domain
Rust Kernel Layer
Bucket
Rust API Membrane
Inferred role
Rust Kernel Layer: implementation source
Status
source implementation candidate

Why This File Exists

Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0

//! Types and functions to work with pointers and addresses.

pub mod projection;
pub use crate::project_pointer as project;

use core::mem::{
    align_of,
    size_of, //
};
use core::num::NonZero;

use crate::const_assert;

/// Type representing an alignment, which is always a power of two.
///
/// It is used to validate that a given value is a valid alignment, and to perform masking and
/// alignment operations.
///
/// This is a temporary substitute for the [`Alignment`] nightly type from the standard library,
/// and to be eventually replaced by it.
///
/// [`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` is not 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<const ALIGN: usize>() -> Self {
        const_assert!(
            ALIGN.is_power_of_two(),
            "Provided alignment is not a 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.
    ///
    /// Returns [`None`] if `align` is 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`.
    ///
    /// This is equivalent to [`align_of`], but with the return value provided as an [`Alignment`].
    #[inline(always)]
    pub const fn of<T>() -> Self {
        // This cannot panic since alignments are always powers of two.

Annotation

Implementation Notes