summaryrefslogtreecommitdiff
path: root/rust/kernel/ptr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel/ptr.rs')
-rw-r--r--rust/kernel/ptr.rs42
1 files changed, 35 insertions, 7 deletions
diff --git a/rust/kernel/ptr.rs b/rust/kernel/ptr.rs
index bdc2d79ff669..3f3e529e9f58 100644
--- a/rust/kernel/ptr.rs
+++ b/rust/kernel/ptr.rs
@@ -11,6 +11,8 @@ use core::mem::{
};
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
@@ -44,12 +46,10 @@ impl Alignment {
/// ```
#[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."
- );
- }
+ 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.
@@ -87,7 +87,6 @@ impl Alignment {
/// This is equivalent to [`align_of`], but with the return value provided as an [`Alignment`].
#[inline(always)]
pub const fn of<T>() -> Self {
- #![allow(clippy::incompatible_msrv)]
// This cannot panic since alignments are always powers of two.
//
// We unfortunately cannot use `new` as it would require the `generic_const_exprs` feature.
@@ -253,3 +252,32 @@ impl<T> KnownSize for [T] {
p.len() * size_of::<T>()
}
}
+
+/// Aligns `value` up to `align`.
+///
+/// This is the const-compatible equivalent of [`Alignable::align_up`].
+///
+/// Returns [`None`] on overflow.
+///
+/// # Examples
+///
+/// ```
+/// use kernel::{
+/// ptr::{
+/// const_align_up,
+/// Alignment, //
+/// },
+/// sizes::SZ_4K, //
+/// };
+///
+/// assert_eq!(const_align_up(0x4f, Alignment::new::<16>()), Some(0x50));
+/// assert_eq!(const_align_up(0x40, Alignment::new::<16>()), Some(0x40));
+/// assert_eq!(const_align_up(1, Alignment::new::<SZ_4K>()), Some(SZ_4K));
+/// ```
+#[inline(always)]
+pub const fn const_align_up(value: usize, align: Alignment) -> Option<usize> {
+ match value.checked_add(align.as_usize() - 1) {
+ Some(v) => Some(v & align.mask()),
+ None => None,
+ }
+}