Skip to content
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

Merged
merged 2 commits into from May 19, 2024
Merged

Conversation

devnexen
Copy link
Contributor

@devnexen devnexen commented May 7, 2024

Fixes #3577

@devnexen devnexen force-pushed the aligned_alloc branch 2 times, most recently from 0552e7a to 3e1a99b Compare May 8, 2024 05:13
@RalfJung
Copy link
Member

RalfJung commented May 8, 2024

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.

@RalfJung
Copy link
Member

RalfJung commented May 8, 2024 via email

@RalfJung
Copy link
Member

RalfJung commented May 9, 2024

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.

@RalfJung
Copy link
Member

RalfJung commented May 9, 2024

I realized I missed an important part of the spec.

Fundamental alignments are always supported.

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?

@RalfJung
Copy link
Member

RalfJung commented May 9, 2024

@rustbot author
(please do rustbot ready when this is ready for the next round of review)

@rustbot rustbot added the S-waiting-on-author Status: Waiting for the PR author to address review comments label May 9, 2024
@RalfJung
Copy link
Member

RalfJung commented May 9, 2024

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.

@RalfJung
Copy link
Member

RalfJung commented May 9, 2024

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

The value of alignment is constrained, it
must be a power of two and it must be greater than or equal to the size of
a word on the platform.

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.

src/shims/unix/foreign_items.rs Show resolved Hide resolved
tests/pass-dep/libc/libc-mem.rs Show resolved Hide resolved
tests/pass-dep/libc/libc-mem.rs Outdated Show resolved Hide resolved
@RalfJung RalfJung changed the title [WIP] support aligned_alloc for unixes support. [WIP] support aligned_alloc for unixes. May 9, 2024
@devnexen devnexen force-pushed the aligned_alloc branch 2 times, most recently from a0914de to de0cb7a Compare May 15, 2024 19:13
@devnexen devnexen marked this pull request as ready for review May 15, 2024 20:52
@devnexen
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Waiting for a review to complete and removed S-waiting-on-author Status: Waiting for the PR author to address review comments labels May 15, 2024
@RalfJung
Copy link
Member

RalfJung commented May 16, 2024

@rustbot author
Please do not mark a PR as ready when there are outstanding comments from the previous review that have not been taken care of yet. Please go over all my comments from the previous review and either make sure they are handled, or argue why you think they shouldn't be handled.

Examples of comments not handled:

There may be more.

@rustbot rustbot added S-waiting-on-author Status: Waiting for the PR author to address review comments and removed S-waiting-on-review Status: Waiting for a review to complete labels May 16, 2024
@devnexen devnexen force-pushed the aligned_alloc branch 2 times, most recently from ab9f83a to 7ea5ccb Compare May 16, 2024 19:41
// 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);
Copy link
Member

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

Comment on lines 307 to 308
// The size must be a multiple of the alignment.
// Alignment must be a power of 2, and "supported by the implementation".
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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.)

// 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// We decide that our implementation supports all alignments.

// 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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.

// 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/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// emulate/
// emulate.

Copy link
Member

@RalfJung RalfJung May 17, 2024

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.

@@ -241,6 +241,42 @@ fn test_reallocarray() {
}
}

#[cfg(not(any(target_os = "windows", target_os = "wasi")))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not on wasi?

Copy link
Contributor Author

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.

Copy link
Member

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.

Comment on lines 263 to 279
// 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);
}
Copy link
Member

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.

fn aligned_alloc(alignment: libc::size_t, size: libc::size_t) -> *mut libc::c_void;
}

unsafe {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unsafe {
// Make sure even zero-sized allocations need to be freed.
unsafe {

@@ -241,6 +241,42 @@ fn test_reallocarray() {
}
}

#[cfg(not(any(target_os = "windows", target_os = "wasi")))]
Copy link
Member

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.

@devnexen
Copy link
Contributor Author

devnexen commented May 17, 2024

alright .. going to reactivate wasi then, we shall see.

@RalfJung
Copy link
Member

RalfJung commented May 17, 2024 via email

@devnexen
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Waiting for a review to complete and removed S-waiting-on-author Status: Waiting for the PR author to address review comments labels May 17, 2024
Comment on lines 271 to 273
for i in 0..16 {
unsafe {
let p = aligned_alloc(i, i);
Copy link
Member

@RalfJung RalfJung May 18, 2024

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.

Copy link
Contributor Author

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.

Comment on lines 10 to 11
// Make sure event zero-sized allocations need to be freed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Make sure event zero-sized allocations need to be freed.
// Make sure even zero-sized allocations need to be freed.

@RalfJung
Copy link
Member

I assume the "WIP" in the PR description can be removed now.

@RalfJung RalfJung changed the title [WIP] support aligned_alloc for unixes. support aligned_alloc for unixes. May 19, 2024
@RalfJung
Copy link
Member

Thanks for bearing with me through all these rounds of review. :)
@bors r+

@bors
Copy link
Collaborator

bors commented May 19, 2024

📌 Commit 78ed7ac has been approved by RalfJung

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented May 19, 2024

⌛ Testing commit 78ed7ac with merge b850b4d...

@bors
Copy link
Collaborator

bors commented May 19, 2024

☀️ Test successful - checks-actions
Approved by: RalfJung
Pushing b850b4d to master...

@bors bors merged commit b850b4d into rust-lang:master May 19, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Waiting for a review to complete
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement aligned_alloc
4 participants