Skip to content

Commit

Permalink
Enable async stack support for MSVC
Browse files Browse the repository at this point in the history
After #619, async stack support is almost possible with MSVC; this PR
makes the final changes to support the feature.
  • Loading branch information
ispeters committed Oct 1, 2024
1 parent 7af55cd commit 1a8a9e0
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 17 deletions.
2 changes: 1 addition & 1 deletion cmake/unifex_env.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ endif()

if (UNIFEX_CXX_COMPILER_MSVC)
# warning level 3 and all warnings as errors
add_compile_options(/W3 /WX)
add_compile_options(/W3 /WX /bigobj)
else()
# lots of warnings and all warnings as errors
add_compile_options(-Wall -Wextra -pedantic -Werror)
Expand Down
12 changes: 9 additions & 3 deletions examples/fp_delegation.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* Licensed under the Apache License Version 2.0 with LLVM Exceptions
* (the "License"); you may not use this file except in compliance with
Expand All @@ -13,6 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined(_MSC_VER) && !defined(__clang__)
// async stacks break this file when building with MSVC; we can probably fix it
// by switching the implementation to use unifex::variant_sender, but that's a
// post-CppCon problem
# define UNIFEX_NO_ASYNC_STACKS 1
#endif

#include <unifex/for_each.hpp>
#include <unifex/manual_event_loop.hpp>
Expand Down Expand Up @@ -135,15 +141,15 @@ class delegating_sender {
auto local_op = [&receiver, context = context_]() mutable {
return LC{unifex::connect(
unifex::schedule(context->single_thread_context_.get_scheduler()),
(Receiver &&) receiver)};
(Receiver&&)receiver)};
};
return op{std::move(local_op), context_};
}

auto target_op = [&receiver]() mutable {
return unifex::connect(
unifex::schedule(unifex::get_scheduler(std::as_const(receiver))),
(Receiver &&) receiver);
(Receiver&&)receiver);
};

return op{std::move(target_op), context_};
Expand Down
20 changes: 11 additions & 9 deletions include/unifex/await_transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,9 @@ class _awaitable_wrapper<Awaitable>::type final {
coro::coroutine_handle<>,
_suspend_result_t<Promise>>;

template(typename Promise) //
(requires same_as<bool, suspend_result_t<Promise>>) //
bool await_suspend_impl(
coro::coroutine_handle<Promise> h, AsyncStackFrame* frame) {
template <typename Promise>
bool await_suspend_bool(
coro::coroutine_handle<Promise> h, AsyncStackFrame* frame) {
auto* root = frame->getStackRoot();

auto resumer = resume_with_stack_root(h).handle();
Expand Down Expand Up @@ -418,10 +417,9 @@ class _awaitable_wrapper<Awaitable>::type final {
}
}

template(typename Promise) //
(requires(!same_as<bool, suspend_result_t<Promise>>)) //
suspend_result_t<Promise> await_suspend_impl(
coro::coroutine_handle<Promise> h, AsyncStackFrame* frame) {
template <typename Promise>
suspend_result_t<Promise> await_suspend_impl(
coro::coroutine_handle<Promise> h, AsyncStackFrame* frame) {
auto resumer = resume_with_stack_root(h).handle();

// save for later destruction
Expand All @@ -437,7 +435,11 @@ class _awaitable_wrapper<Awaitable>::type final {
template <typename Promise>
suspend_result_t<Promise> await_suspend(coro::coroutine_handle<Promise> h) {
if (auto* frame = get_async_stack_frame(h.promise())) {
return await_suspend_impl(h, frame);
if constexpr (same_as<bool, suspend_result_t<Promise>>) {
return await_suspend_bool(h, frame);
} else {
return await_suspend_impl(h, frame);
}
}

using awaiter_suspend_result_t = decltype(awaiter_.await_suspend(h));
Expand Down
6 changes: 2 additions & 4 deletions include/unifex/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,11 +301,9 @@
#if !defined(UNIFEX_NO_ASYNC_STACKS)
// default:
// - release builds do not have async stacks
// - Windows builds do not have async stacks
//
// adding async stacks adds non-trivial binary size at the moment, and I can't
// figure out how to make all the relevant Windows builds succeed
# if defined(NDEBUG) || defined(_MSC_VER)
// adding async stacks adds non-trivial binary size at the moment
# if defined(NDEBUG)
# define UNIFEX_NO_ASYNC_STACKS 1
# else
# define UNIFEX_NO_ASYNC_STACKS 0
Expand Down

0 comments on commit 1a8a9e0

Please sign in to comment.