Skip to content

Rust crate for type-level byte alignment guarantees.

License

Notifications You must be signed in to change notification settings

V0ldek/aligners

Repository files navigation

aligners – strongly typed memory alignment guarantees

Rust Miri docs.rs

Crates.io GitHub Release Date GitHub last commit

Crates.io

Some bytes just need to be aligned. Want to process bytes in batches of 8 by interpreting them as u64? They must be 8-byte aligned. Want to run SIMD operations on your bytes? You need to use special unaligned instructions and risk performance, or align them with target's requirements. Maybe your high-performance algorithm requires page alignment?

Validating that something is aligned is hard. aligners solves this problem by introducing strongly typed alignment types. To have your bytes aligned to a page boundary on the target architecture, all you need to do is:

use aligners::{alignment, AlignedBytes};

let bytes: [u8; 8] = [ 1, 2, 3, 4, 5, 6, 7, 8 ];
let aligned: AlignedBytes<alignment::Page> = bytes.into();

That's it. AlignedBytes<A> owns the bytes. By taking a reference you get &AlignedSlice<A>, which is basically the same as &[u8], only that its alignment is guaranteed by the type.

Status

This crate is under active development and the API is unstable. It contains the MVP of being able to align your bytes to page or SIMD-block boundary and iterate over aligned blocks.

The crate is continuously built and tested on a number of architectures. We also use Miri on multiple target triples to test for hard-to-find bugs.

Unsafety

This crate needs to use unsafe code due to the low-level pointer-twiddling nature of the domain. Two places where unsafe is required are:

  • creating the AlignedBytes, as it requires explicitly working with the allocator to get properly aligned bytes;
  • converting between AlignedSlice and regular byte slices, which relies on repr(transparent) of the former to be mem::transmute-able into the latter.
  • working internally on AlignedBlock to maintain the type's invariants.

Reviews via cargo-crev are appreciated.

Dependencies

Dependencies graph generated by cargo-deps:

 dependencies graph

Or as the output of cargo tree:

aligners v0.0.1
├── cfg-if v1.0.0
├── lazy_static v1.4.0
└── page_size v0.4.2
    └── libc v0.2.125

Justification

  • cfg-if – used to configure conditional compilation in a more readable manner, especially determining SIMD block size. It's lightweight and contains no unsafe code.
  • lazy_static – used to lazily validate and cache the page size.
  • page_size – used to get the page size for alignment::Page.

Dev

  • cargo-hack – used for more robust testing by compiling and running the code for the feature powerset.
  • anyhow – used in the simd_alignment_test to make error handling easy.

crev

It is recommended to always use cargo-crev to verify the trustworthiness of each of your dependencies, including this one. Reviews are appreciated.

To add me to your WoT trust my crev-proof repo:

cargo crev trust id https://github.com/V0ldek/crev-proofs