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

Referencing stack memory and a @frame pointer before suspending #76

Open
jorangreef opened this issue Jan 6, 2021 · 2 comments
Open
Labels
accepted accepted proposal proposal

Comments

@jorangreef
Copy link

jorangreef commented Jan 6, 2021

Hey @Sobeston thanks for ziglearn! It's been a huge help learning Zig.

Just an idea to add to the Async section:

Normally, passing a pointer to a struct allocated on the stack to another function somewhere else is verboten because it's UB (the stack memory disappears and becomes undefined once the function returns).

However, with suspend, it seems like a common pattern is to do exactly this, with a struct allocated on the stack including some data as well as the @frame pointer, and then passing the @ptrToInt of the pointer to this struct somewhere else, e.g. as the user data when submitting an io_uring sqe.

Here are two real world examples from @kprotty and @daurnimator:

https://gist.github.com/kprotty/c01630ae285e8b14cb7a36c454ac2d87#file-uring_async-zig-L101-L102
https://gist.github.com/daurnimator/699320cda828303671a21d15bb4a3753#file-uring-nonblock-fifo-async-zig-L128-L140

I guess this is obvious to people (and really easy!), but for me as a newcomer this was not something I would have thought of because I don't really understand what happens to the async stack after the suspend, and because usually it's not safe to take a pointer to stack memory.

It would be great to see an example of this in the Async section for ziglearn, an explanation that it's safe, and why it works in the case of suspend, showing how suspend keeps the async frame and its stack allocated variables safe... just so people can get going with suspend quicker (assuming they need to) without worrying that they need to do heap allocation.

@Sobeston Sobeston added proposal accepted accepted proposal labels Jan 6, 2021
@daurnimator
Copy link

Normally, passing a pointer to a struct allocated on the stack to another function somewhere else is verboten because it's UB (the stack memory disappears and becomes undefined once the function returns).

Not exactly.

Something like this is entirely valid and normal:

fn foo() void {
   var buf: [100]u8 = undefined;
   bar(&buf);
}

The key thing is not return-ing a pointer to stack memory (or allowing the stack pointer out into the world for longer than after you return).

And suspend is not return.

@jorangreef
Copy link
Author

The key thing is not return-ing a pointer to stack memory (or allowing the stack pointer out into the world for longer than after you return).

Yes, thanks for clarifying, that was the UB I had in mind (the stack memory disappears and becomes undefined once the function returns).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted accepted proposal proposal
Projects
None yet
Development

No branches or pull requests

3 participants