-
Notifications
You must be signed in to change notification settings - Fork 356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support aligned_alloc for unixes. #3585
Conversation
0552e7a
to
3e1a99b
Compare
Thanks for the PR! This is for #3577, right? When a PR works on an issue, please mention the issue in the PR description. Generally, PR descriptions should hardly ever be empty. Please spend a bit of time giving context to the change -- which issue it resolves, which new feature it implements and how, things like that. It makes review a lot easier. |
We should only support it on platforms that have it in libc.
Do it like the other similar functions: `cfg(not(any(...)))` in the test, and a check against the target OS in the implementation. We shouldn't pretend support on OSes that don't have support.
In some cases maybe the OS has support but the libc crate does not -- in that case, that should be filed as an issue against the libc crate.
|
On size 0 this should probably behave like #3580. That's already what you implemented now, but there should be tests ensuring we detect the memory leak when a size-zero allocation was not freed, and size-0-double-free. |
I realized I missed an important part of the spec.
So... I think we have to support small alignments as well. I think the point of the posix_memalign example is to mention that the alignment must be a power of two? |
@rustbot author |
Looking at the libc crate, it doesn't seem like it has this function on any target we support. 😂 Okay, so... how do we find out which targets support this function? Linux definitely does, at least I have a manpage for it. |
I did a bit of googling and found evidence that it exists for all platforms we support (see the links in rust-lang/libc#3689). For Iluumos the man page says
That is clearly a violation of the C standard, and hence a platform bug. I don't think we should emulate that. So, yeah seems fine to just implement it on all targets then (with it being a C11 standard function -- that's more than 10 years old at this point), and declare it in the test like you did. |
a0914de
to
de0cb7a
Compare
@rustbot ready |
@rustbot author Examples of comments not handled: There may be more. |
ab9f83a
to
7ea5ccb
Compare
src/shims/unix/foreign_items.rs
Outdated
// FreeBSD: https://man.freebsd.org/cgi/man.cgi?query=aligned_alloc&apropos=0&sektion=3&manpath=FreeBSD+9-current&format=html | ||
match size.checked_rem(align) { | ||
Some(0) if align.is_power_of_two() => { | ||
let align = this.min_align(align, size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just use align.max(this.malloc_align(size))
, no need to write a new function for that
src/shims/unix/foreign_items.rs
Outdated
// The size must be a multiple of the alignment. | ||
// Alignment must be a power of 2, and "supported by the implementation". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// The size must be a multiple of the alignment. | |
// Alignment must be a power of 2, and "supported by the implementation". | |
// Alignment must be a power of 2, and "supported by the implementation". | |
// We decide that "supported by the implementation" means that the | |
// size must be a multiple of the alignment. (This restriction seems common | |
// enough that it is stated on <https://en.cppreference.com/w/c/memory/aligned_alloc> | |
// as a general rule, but the actual standard has no such rule.) |
src/shims/unix/foreign_items.rs
Outdated
// Alignment must be a power of 2, and "supported by the implementation". | ||
// If any of these are violated, we have to return NULL. | ||
// All fundamental alignments must be supported. | ||
// We decide that our implementation supports all alignments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// We decide that our implementation supports all alignments. |
src/shims/unix/foreign_items.rs
Outdated
// We decide that our implementation supports all alignments. | ||
// | ||
// macOS and Illumos are buggy in that they require the alignment | ||
// to be at least the size of a pointer. We do not emulate those platform bugs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// to be at least the size of a pointer. We do not emulate those platform bugs. | |
// to be at least the size of a pointer, so they do not support all fundamental | |
// alignments. We do not emulate those platform bugs. |
src/shims/unix/foreign_items.rs
Outdated
// to be at least the size of a pointer. We do not emulate those platform bugs. | ||
// | ||
// Linux also sets errno to EINVAL, but that's non-standard behavior that we do not | ||
// emulate/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// emulate/ | |
// emulate. |
tests/fail-dep/libc/aligned_alloc.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please name the test aligned_alloc_size_zero_leak or so to indicate what it tests.
tests/pass-dep/libc/libc-mem.rs
Outdated
@@ -241,6 +241,42 @@ fn test_reallocarray() { | |||
} | |||
} | |||
|
|||
#[cfg(not(any(target_os = "windows", target_os = "wasi")))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not on wasi?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ve seen unsupported operation for this platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where have you seen that? libc even declares aligned_alloc for wasi so I'd think that it exists there.
tests/pass-dep/libc/libc-mem.rs
Outdated
// alignment lesser than a word but still a successful allocation | ||
unsafe { | ||
let p = aligned_alloc(1, 4); | ||
assert!(!p.is_null()); | ||
assert!(p.is_aligned_to(4)); | ||
libc::free(p); | ||
} | ||
|
||
// finally .. | ||
unsafe { | ||
let p = aligned_alloc(16, 16); | ||
assert!(!p.is_null()); | ||
assert!(p.is_aligned_to(16)); | ||
libc::free(p); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe put these in a for _ in 0..16
or so, because the actual alignment is random so we want to get some extra test coverage.
tests/fail-dep/libc/aligned_alloc.rs
Outdated
fn aligned_alloc(alignment: libc::size_t, size: libc::size_t) -> *mut libc::c_void; | ||
} | ||
|
||
unsafe { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unsafe { | |
// Make sure even zero-sized allocations need to be freed. | |
unsafe { |
tests/pass-dep/libc/libc-mem.rs
Outdated
@@ -241,6 +241,42 @@ fn test_reallocarray() { | |||
} | |||
} | |||
|
|||
#[cfg(not(any(target_os = "windows", target_os = "wasi")))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where have you seen that? libc even declares aligned_alloc for wasi so I'd think that it exists there.
alright .. going to reactivate wasi then, we shall see. |
Oh d'oh, wasi is not a unix, I keep forgetting that. Sorry!
We shouldn't duplicate the function. Please either move the function to alloc.rs so it can be shared - or it's also okay to remove wasi again and leave it to future work.
|
@rustbot ready |
tests/pass-dep/libc/libc-mem.rs
Outdated
for i in 0..16 { | ||
unsafe { | ||
let p = aligned_alloc(i, i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the point of this -- most of these numbers aren't even valid alignments?
I asked you to run the exact same test 16 times in a loop as allocation involves non-determinism.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah ok I did not get you.
// Make sure event zero-sized allocations need to be freed. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Make sure event zero-sized allocations need to be freed. | |
// Make sure even zero-sized allocations need to be freed. |
I assume the "WIP" in the PR description can be removed now. |
Thanks for bearing with me through all these rounds of review. :) |
☀️ Test successful - checks-actions |
Fixes #3577