Skip to content

coroutine frame from lambda #91123

@kelbon

Description

@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

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));
  }
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    coroutinesC++20 coroutineslambdaC++11 lambda expressions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions