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

Reenable SBO in any_sender and friends #1281

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

// SBO is currently disabled as it seems to be buggy in certain use cases. It can still be
// explicitly forced to on by defining PIKA_DETAIL_ENABLE_ANY_SENDER_SBO.
// TODO: Remove definition or enable unconditionally.
#define PIKA_DETAIL_ENABLE_ANY_SENDER_SBO

namespace pika::detail {
template <typename T>
Expand Down Expand Up @@ -134,7 +136,7 @@ namespace pika::detail {
bool using_embedded_storage() const noexcept
{
#if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO)
return object == reinterpret_cast<base_type const*>(&embedded_storage);
return object == static_cast<void const*>(embedded_storage);
#else
return false;
#endif
Expand Down Expand Up @@ -169,15 +171,12 @@ namespace pika::detail {
#if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO)
if (other.using_embedded_storage())
{
auto p = reinterpret_cast<base_type*>(&embedded_storage);
other.get().move_into(p);
object = p;
object = other.get().move_into(embedded_storage);
}
else
#endif
{
heap_storage = other.heap_storage;
other.heap_storage = nullptr;
heap_storage = std::exchange(other.heap_storage, nullptr);
object = heap_storage;
}

Expand All @@ -198,15 +197,12 @@ namespace pika::detail {
#if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO)
if (other.using_embedded_storage())
{
auto p = reinterpret_cast<base_type*>(&embedded_storage);
other.get().move_into(p);
object = p;
object = other.get().move_into(embedded_storage);
}
else
#endif
{
heap_storage = other.heap_storage;
other.heap_storage = nullptr;
heap_storage = std::exchange(other.heap_storage, nullptr);
object = heap_storage;
}

Expand Down Expand Up @@ -276,9 +272,7 @@ namespace pika::detail {
#if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO)
if constexpr (can_use_embedded_storage<Impl>())
{
Impl* p = reinterpret_cast<Impl*>(&embedded_storage);
new (p) Impl(std::forward<Ts>(ts)...);
object = p;
object = new (embedded_storage) Impl(std::forward<Ts>(ts)...);
}
else
#endif
Expand Down Expand Up @@ -323,9 +317,7 @@ namespace pika::detail {
#if defined(PIKA_DETAIL_ENABLE_ANY_SENDER_SBO)
if (other.using_embedded_storage())
{
base_type* p = reinterpret_cast<base_type*>(&embedded_storage);
other.get().clone_into(p);
object = p;
object = other.get().clone_into(embedded_storage);
}
else
#endif
Expand Down Expand Up @@ -581,24 +573,25 @@ namespace pika::execution::experimental::detail {
struct unique_any_sender_base
{
virtual ~unique_any_sender_base() noexcept = default;
virtual void move_into(void* p) = 0;
virtual unique_any_sender_base<Ts...>* move_into(unsigned char* p) = 0;
virtual any_operation_state_holder connect(any_receiver<Ts...>&& receiver) && = 0;
virtual bool empty() const noexcept { return false; }
};

template <typename... Ts>
struct any_sender_base : public unique_any_sender_base<Ts...>
{
virtual any_sender_base<Ts...>* move_into(unsigned char* p) = 0;
virtual any_sender_base* clone() const = 0;
virtual void clone_into(void* p) const = 0;
virtual any_sender_base<Ts...>* clone_into(unsigned char* p) const = 0;
using unique_any_sender_base<Ts...>::connect;
virtual any_operation_state_holder connect(any_receiver<Ts...>&& receiver) const& = 0;
};

template <typename... Ts>
struct empty_unique_any_sender final : unique_any_sender_base<Ts...>
{
void move_into(void*) override { PIKA_UNREACHABLE; }
unique_any_sender_base<Ts...>* move_into(unsigned char*) override { PIKA_UNREACHABLE; }

bool empty() const noexcept override { return true; }

Expand All @@ -611,11 +604,11 @@ namespace pika::execution::experimental::detail {
template <typename... Ts>
struct empty_any_sender final : any_sender_base<Ts...>
{
void move_into(void*) override { PIKA_UNREACHABLE; }
any_sender_base<Ts...>* move_into(unsigned char*) override { PIKA_UNREACHABLE; }

any_sender_base<Ts...>* clone() const override { PIKA_UNREACHABLE; }

void clone_into(void*) const override { PIKA_UNREACHABLE; }
any_sender_base<Ts...>* clone_into(unsigned char*) const override { PIKA_UNREACHABLE; }

bool empty() const noexcept override { return true; }

Expand Down Expand Up @@ -645,7 +638,10 @@ namespace pika::execution::experimental::detail {

~unique_any_sender_impl() noexcept = default;

void move_into(void* p) override { new (p) unique_any_sender_impl(std::move(sender)); }
unique_any_sender_base<Ts...>* move_into(unsigned char* p) override
{
return new (p) unique_any_sender_impl(std::move(sender));
}

any_operation_state_holder connect(any_receiver<Ts...>&& receiver) && override
{
Expand All @@ -667,11 +663,17 @@ namespace pika::execution::experimental::detail {

~any_sender_impl() noexcept = default;

void move_into(void* p) override { new (p) any_sender_impl(std::move(sender)); }
any_sender_base<Ts...>* move_into(unsigned char* p) override
{
return new (p) any_sender_impl(std::move(sender));
}

any_sender_base<Ts...>* clone() const override { return new any_sender_impl(sender); }

void clone_into(void* p) const override { new (p) any_sender_impl(sender); }
any_sender_base<Ts...>* clone_into(unsigned char* p) const override
{
return new (p) any_sender_impl(sender);
}

any_operation_state_holder connect(any_receiver<Ts...>&& receiver) const& override
{
Expand Down
Loading