Allow aligned allocations in NIFs
Is your feature request related to a problem? Please describe.
When using Rust (via Rustler) it would be handy to have a way to use Rust GlobalAlloc with enif_alloc function. The problem is that enif_alloc do not have counterpart that allows passing alignment, which would be needed there. This can sometimes lead to SIGBUS errors.
Describe the solution you'd like
Have another allocation function (for example void *enif_alloc_aligned(size_t size, size_t alignment)) that would allow to explicitly set the alignment. It will then pick the max(erlang_alignment, alignment) and will use that as the target alignment (AFAIK we can always expand alignment, but never contract it).
With such hypothetical function we could then implement Rust GlobalAlloc as:
struct ErlGlobalAlloc;
unsafe impl GlobalAlloc for ErlGlobalAlloc {
fn alloc(&self, layout: Layout) -> *mut u8 {
enif_alloc_aligned(layout.size, layout.align)
}
// Rest of the functions
}
Describe alternatives you've considered
I was thinking about implementing this as try and error or by doing some extra magic with allocating more memory than needed and then storing required metadata there, but all of that is just set of hacks, that could be instead implemented directly in OTP.
Additional context
I believe that it would be useful to have such function, as it may help with having Rust global allocator that will allow introspection and observability of memory usage in Rustler NIFs.
I see that there already is such function in ERTS, but I am not experienced enough right now to come up with an idea how to expose such function there.
I see that there already is such function in ERTS
What function are you referring to?
erts_sys_aligned_alloc in erts/emulator/sys/unix/sys.c and erts/emulator/sys/win32/sys.c
I'm also in need of this (or something similar). For me, I am attempting to use enif_alloc_resource with SIMD intrinsics. From what I'm seeing, __m256d (4 packed doubles) requires a 32 byte alignment, but the address given by enif_alloc_resource is often not properly aligned, causing a crash.
@hauleth I added GlobalAlloc support for Rustler a while ago in https://github.com/rusterlium/rustler/pull/580. A custom alignment for enif_alloc would still be highly appreciated, less code is always better :)
I'll try to create a PR for this.
currently tracking it in zigler:
https://github.com/E-xyza/zigler/issues/488
though here we use a custom allocator for wide alignments:
https://github.com/E-xyza/zigler/blob/93f9526e477867770e5f075343b1f396e000d704/priv/beam/allocator.zig#L86-L132
If there's a better internally supported choice, that would be amazing.