Skip to content

Commit 5459545

Browse files
committed
zephyr: Add alignment helper
The Rust attribute that indicates structure alignment only supports alignment values that are numeric constants. This makes it difficult to set alignment based on a value coming from the build environment, which is commonly done. Implement a bit of a workaround with an `AlignAs` type that is parameterized with the alignment. Parameters can be compile-time constants not just numeric constants. This works by having instances for each of the desired alignments that each have the numeric constant as the alignment. The instances can be expanded if necessary. Signed-off-by: David Brown <[email protected]>
1 parent f9f447c commit 5459545

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

zephyr/src/align.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//! Alignment
2+
//!
3+
//! Natively, the align attribute in rust does not allow anything other than an integer literal.
4+
//! However, Zephyr will define the external alignment based on numeric constants. This defines a
5+
//! bit of a trick to enforce alignment of structs to values by defined constants.
6+
//!
7+
//! Thanks to Chayim Refael Friedman for help with this.
8+
9+
pub struct AlignAsStruct;
10+
11+
pub trait AlignAsTrait<const N: usize> {
12+
type Aligned;
13+
}
14+
15+
macro_rules! impl_alignas {
16+
( $($align:literal),* $(,)? ) => {
17+
$(
18+
const _: () = {
19+
#[repr(align($align))]
20+
pub struct Aligned;
21+
impl AlignAsTrait<$align> for AlignAsStruct {
22+
type Aligned = Aligned;
23+
}
24+
};
25+
)*
26+
};
27+
}
28+
// This can be expanded as needed.
29+
impl_alignas!(1, 2, 4, 8, 16, 32, 64, 128, 256);
30+
31+
/// Align a given struct to a given alignment. To use this, just include `AlignAs<N>` as the first
32+
/// member of the struct.
33+
#[repr(transparent)]
34+
pub struct AlignAs<const N: usize>([<AlignAsStruct as AlignAsTrait<N>>::Aligned; 0])
35+
where
36+
AlignAsStruct: AlignAsTrait<N>;

zephyr/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#![no_std]
8585
#![allow(unexpected_cfgs)]
8686

87+
pub mod align;
8788
pub mod object;
8889
pub mod sync;
8990
pub mod sys;

0 commit comments

Comments
 (0)