Issue |
91123
|
Summary |
coroutine frame from lambda
|
Labels |
new issue
|
Assignees |
|
Reporter |
kelbon
|
I think there are should be a way to create coroutine frame from lambda. There are use cases:
* when we sure dont need allocation here, just create a handle and pass into function which accepts coroutine handles
* when coroutine handle may be invoked concurrently from different threads ('when_any' implementation), but its not possible in standard C++ to handle this (calling .resume concurrently will lead to UB). With lambdas calling .resume concurrently may be handled with simple mutex
* to create 'always done' coroutine, just like std::noop_coroutine, but .done always returns true
* to create special coroutines, such as generator, which is always empty (without allocatons). This may be used in std::generator move operator (there are no default constructor for std::generator, but move constructor is present, so to create "default" state for such generator we can use some global generator object, which .resume does nothing and .destroy does nothing too)
I have "implementation", but for obvious reasons it is not good: it contains undefined behavior. And i dont know is it intentional, but clang ignores all noinline and std::launder hacks and just optimizes out all code every time (with O1/O2/O3):
https://godbolt.org/z/EP1b8Eb9x
```cpp
template <typename F>
struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) coroutine_frame {
void (*resume)(void*) = &do_resume<std::decay_t<coroutine_frame>>;
void (*destroy)(void*) = &do_destroy<std::decay_t<coroutine_frame>>;
F f;
coroutine_frame(F value) : f(std::move(value)) {}
[[gnu::noinline]] std::coroutine_handle<> handle() noexcept {
return std::coroutine_handle<>::from_address(std::launder(this));
}
};
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs