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 break in suspend blocks #803

Closed
andrewrk opened this issue Mar 3, 2018 · 4 comments · Fixed by #1307
Closed

support break in suspend blocks #803

andrewrk opened this issue Mar 3, 2018 · 4 comments · Fixed by #1307
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Mar 3, 2018

Internally, await is a suspend block that reaches into the coroutine's frame, atomically modifies the awaiter pointer, and then based on the previous value of the awaiter pointer, might decide not to suspend after all.

We could expose this ability to zig programmers, like this:

suspend |p| {
    const prev_value = @atomicRmw(usize, &something, AtomicRmwOp.Xchg, something_else, AtomicOrder.SeqCst);
    if (prev_value == 0) {
        queue(p);
    } else {
        break;
    }
}
@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Mar 3, 2018
@andrewrk andrewrk added this to the 0.3.0 milestone Mar 3, 2018
@andrewrk
Copy link
Member Author

andrewrk commented Mar 4, 2018

This feature can be used in a couple of interesting ways with a thread pool:

Switch the current function to running in another thread, and run another function in the current thread:

suspend |p| {
    threadPoolResume(p);
    anotherFunction();
    break;
}

Fork the current function, running it in 2 kernel threads simultaneously:

suspend |p| {
    threadPoolResume(p);
    break;
}

@andrewrk
Copy link
Member Author

andrewrk commented Mar 5, 2018

Also related is what to do when returning from a suspend block:

        suspend |p| {
            var ev = std.os.linux.epoll_event {
                .events = EPOLLIN|EPOLLET,
                .data = std.os.linux.epoll_data {
                    .ptr = @ptrToInt(p),
                },
            };
            try epoll_ctl(self.epollfd, EPOLL_CTL_ADD, fd, &ev);
        }

@andrewrk andrewrk added the accepted This proposal is planned. label Apr 16, 2018
andrewrk added a commit that referenced this issue Apr 19, 2018
 * you can label suspend blocks
 * labeled break supports suspend blocks

See #803
@andrewrk
Copy link
Member Author

andrewrk commented Apr 19, 2018

  • labeled suspend blocks
  • ability to break from labeled suspend block
  • handle returning from suspend block (think about try carefully). it might already work correctly actually. return/try just cancels the suspend and then does a normal return/try. but let's add some test cases.
  • update std.zig.parser to handle the new syntax
  • documentation

@andrewrk andrewrk added rejected and removed accepted This proposal is planned. labels Jul 27, 2018
@andrewrk
Copy link
Member Author

Instead of breaking from a suspend block, you have to resume your own handle. It works fine - just make sure it's a tail call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant