Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions include/exec/libdispatch_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ namespace experimental::execution

struct libdispatch_scheduler
{
using scheduler_concept = STDEXEC::scheduler_tag;

bool operator==(libdispatch_scheduler const &) const = default;

struct domain
Expand Down
2 changes: 2 additions & 0 deletions include/exec/linux/io_uring_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,8 @@ namespace experimental::execution
class __scheduler
{
public:
using scheduler_concept = STDEXEC::scheduler_tag;

__context* __context_;

auto operator==(__scheduler const &) const -> bool = default;
Expand Down
2 changes: 2 additions & 0 deletions include/exec/reschedule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ namespace experimental::execution

struct __scheduler
{
using scheduler_concept = scheduler_tag;

struct __sender
{
using sender_concept = sender_tag;
Expand Down
2 changes: 2 additions & 0 deletions include/exec/static_thread_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ namespace experimental::execution

struct scheduler
{
using scheduler_concept = scheduler_tag;

private:
template <class Receiver>
friend struct _opstate;
Expand Down
2 changes: 2 additions & 0 deletions include/exec/thread_pool_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ namespace experimental::execution

struct scheduler
{
using scheduler_concept = STDEXEC::scheduler_tag;

private:
template <class DerivedPoolType_, class Receiver>
friend struct _pool_::opstate;
Expand Down
5 changes: 3 additions & 2 deletions include/exec/timed_thread_scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,9 @@ namespace experimental::execution
class timed_thread_scheduler
{
public:
using time_point = std::chrono::steady_clock::time_point;
using duration = std::chrono::steady_clock::duration;
using scheduler_concept = STDEXEC::scheduler_tag;
using time_point = std::chrono::steady_clock::time_point;
using duration = std::chrono::steady_clock::duration;

class schedule_at_sender
{
Expand Down
2 changes: 2 additions & 0 deletions include/exec/trampoline_scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ namespace experimental::execution
std::size_t __max_recursion_size_;

public:
using scheduler_concept = scheduler_tag;

constexpr __scheduler() noexcept
: __attrs{16}
, __max_recursion_size_(4096)
Expand Down
3 changes: 2 additions & 1 deletion include/exec/windows/windows_thread_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,8 @@ namespace experimental::execution::__win32
class windows_thread_pool::scheduler
{
public:
using time_point = filetime_clock::time_point;
using scheduler_concept = STDEXEC::scheduler_tag;
using time_point = filetime_clock::time_point;

[[nodiscard]]
auto schedule() const noexcept -> schedule_sender
Expand Down
2 changes: 2 additions & 0 deletions include/nvexec/multi_gpu_context.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ namespace nv::execution
{
struct multi_gpu_stream_scheduler : private stream_scheduler_env<multi_gpu_stream_scheduler>
{
using scheduler_concept = STDEXEC::scheduler_tag;

multi_gpu_stream_scheduler(int num_devices, context ctx)
: num_devices_(num_devices)
, ctx_(ctx)
Expand Down
2 changes: 2 additions & 0 deletions include/nvexec/stream_context.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ namespace nv::execution

struct stream_scheduler : private stream_scheduler_env<stream_scheduler>
{
using scheduler_concept = STDEXEC::scheduler_tag;

explicit stream_scheduler(context ctx) noexcept
: ctx_(ctx)
{}
Expand Down
2 changes: 2 additions & 0 deletions include/stdexec/__detail/__parallel_scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ namespace STDEXEC
class parallel_scheduler
{
public:
using scheduler_concept = scheduler_tag;

parallel_scheduler() = delete;

/// Returns `true` iff `*this` refers to the same scheduler as the argument.
Expand Down
38 changes: 38 additions & 0 deletions test/exec/test_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
# include <exec/async_scope.hpp>
# include <exec/sender_for.hpp>
# include <exec/single_thread_context.hpp>
# include <exec/static_thread_pool.hpp>
# include <exec/task.hpp>
# include <exec/timed_thread_scheduler.hpp>

# include <test_common/schedulers.hpp>

Expand Down Expand Up @@ -370,6 +372,42 @@ namespace
CHECK(count == 3);
}
# endif // !STDEXEC_NO_STDCPP_EXCEPTIONS()

// Regression tests for https://github.com/NVIDIA/stdexec/issues/2134: the
// schedulers of exec::static_thread_pool and exec::timed_thread_context used
// to be missing the `scheduler_concept` nested alias required by the
// scheduler concept, which made exec::task's internal __any_scheduler
// conversion fail to compile when such a task was co_started on them.
TEST_CASE("task - can be started on a static_thread_pool scheduler", "[types][task]")
{
exec::static_thread_pool pool{2};
bool ran = false;
// Keep the closure a temporary inside the full expression: the task is
// lazy, so the closure (and its by-reference capture) must outlive the
// point at which the pool thread resumes the coroutine.
auto op_state = STDEXEC::sync_wait(STDEXEC::starts_on(pool.get_scheduler(),
[&]() -> exec::task<void>
{
ran = true;
co_return;
}()));
REQUIRE(op_state);
CHECK(ran);
}

TEST_CASE("task - can be started on a timed_thread_context scheduler", "[types][task]")
{
exec::timed_thread_context ctx;
bool ran = false;
auto op_state = STDEXEC::sync_wait(STDEXEC::starts_on(ctx.get_scheduler(),
[&]() -> exec::task<void>
{
ran = true;
co_return;
}()));
REQUIRE(op_state);
CHECK(ran);
}
} // namespace

#endif
Loading