Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
scheduler.hpp
Go to the documentation of this file.
1
3
4// see https://github.com/dbittman/waitfree-mpsc-queue/blob/master/mpsc.c
5
6#pragma once
7
8#include "async_task.hpp"
9
10#include <concepts>
11#include <cstddef>
12#include <functional>
13#include <memory>
14#include <thread>
15#include <type_traits>
16#include <utility>
17
18namespace uni20::async
19{
20
21class AsyncTask;
22class TaskPromiseBase;
23
29 public:
34 template <class Function>
35 requires std::invocable<Function&, std::size_t>
36 static auto bind(std::size_t size, Function& function) -> LightweightTaskBatch
37 {
38 using function_type = std::remove_reference_t<Function>;
40 size, const_cast<void*>(static_cast<void const*>(std::addressof(function))),
41 [](void* context, std::size_t index) { std::invoke(*static_cast<function_type*>(context), index); }};
42 }
43
45 [[nodiscard]] auto size() const noexcept -> std::size_t { return size_; }
46
49 void operator()(std::size_t index) const { invoke_(context_, index); }
50
51 private:
52 using invoke_type = void (*)(void*, std::size_t);
53
54 LightweightTaskBatch(std::size_t size, void* context, invoke_type invoke) noexcept
55 : size_(size), context_(context), invoke_(invoke)
56 {}
57
58 std::size_t size_;
59 void* context_;
60 invoke_type invoke_;
61};
62
65 public:
67 virtual ~IScheduler() = default;
68
69 private:
70 friend class BasicTask;
71 friend class TaskPromiseBase;
72
76 virtual bool accepts_route(TaskRoute route) const noexcept = 0;
77
81 virtual bool can_direct_transfer(TaskHandle from, TaskHandle to) const noexcept = 0;
82
85 virtual void reschedule(BasicTask&& task) = 0;
86};
87
89class IAsyncScheduler : public virtual IScheduler {
90 public:
92 ~IAsyncScheduler() override = default;
93
96 virtual void schedule(AsyncTask&& task) = 0;
97
111 template <class Function>
112 requires std::invocable<Function&, std::size_t>
113 void execute_batch(std::size_t size, Function&& function)
114 {
115 auto batch = LightweightTaskBatch::bind(size, function);
116 this->execute_batch_impl(batch);
117 }
118
121 virtual void pause() = 0;
122
125 virtual void resume() = 0;
126
127 using WaitPredicate = std::function<bool()>;
128 using WaitWakeup = std::function<void()>;
129 using WaitWakeupRegistration = std::function<void(WaitWakeup)>;
130
144
152 virtual void help_while_waiting(const WaitPredicate& is_ready)
153 {
154 while (!is_ready())
155 {
156 std::this_thread::yield();
157 }
158 }
159
166 virtual void wait_for(const WaitPredicate& is_ready)
167 {
168 while (!is_ready())
169 {
170 this->help_while_waiting(is_ready);
171 }
172 }
173
181 virtual void wait_for(WaitRequest const& request) { this->wait_for(request.is_ready); }
182
183 private:
186 virtual void execute_batch_impl(LightweightTaskBatch const& batch)
187 {
188 for (std::size_t index = 0; index < batch.size(); ++index)
189 batch(index);
190 }
191};
192
193} // namespace uni20::async
Promise-neutral coroutine task ownership and the public AsyncTask type.
Canonical host-oriented coroutine task type.
Definition async_task.hpp:196
Move-only promise-neutral ownership claim for a Uni20 coroutine.
Definition async_task.hpp:103
Scheduler interface for initial AsyncTask submission and host-side progress.
Definition scheduler.hpp:89
virtual void pause()=0
Pause the scheduler.
virtual void help_while_waiting(const WaitPredicate &is_ready)
Allow a scheduler to advance queued work while a thread is blocking.
Definition scheduler.hpp:152
std::function< void(WaitWakeup)> WaitWakeupRegistration
Definition scheduler.hpp:129
std::function< void()> WaitWakeup
Definition scheduler.hpp:128
std::function< bool()> WaitPredicate
Definition scheduler.hpp:127
~IAsyncScheduler() override=default
Virtual destructor.
virtual void schedule(AsyncTask &&task)=0
Schedule a coroutine for its initial execution.
virtual void wait_for(WaitRequest const &request)
Block until a structured wait request becomes ready.
Definition scheduler.hpp:181
virtual void wait_for(const WaitPredicate &is_ready)
Block the calling thread until is_ready returns true.
Definition scheduler.hpp:166
virtual void resume()=0
Resume the scheduler.
void execute_batch(std::size_t size, Function &&function)
Execute a synchronous batch of independent lightweight work items.
Definition scheduler.hpp:113
Internal route for resuming an already-bound coroutine task.
Definition scheduler.hpp:64
virtual ~IScheduler()=default
Virtual destructor.
Borrowed type-erased description of a synchronous lightweight task batch.
Definition scheduler.hpp:28
void operator()(std::size_t index) const
Execute one work item.
Definition scheduler.hpp:49
auto size() const noexcept -> std::size_t
Return the number of independent work items.
Definition scheduler.hpp:45
static auto bind(std::size_t size, Function &function) -> LightweightTaskBatch
Bind a callable for the duration of one synchronous batch call.
Definition scheduler.hpp:36
Non-owning erased identity for one Uni20 coroutine frame.
Definition async_task.hpp:59
Shared non-polymorphic implementation for Uni20 task promises.
Definition async_task_promise.hpp:99
Definition qnum.hpp:403
This represents the reverse-mode adjoint for functions of complex variables, assuming a real-valued s...
Definition async/async.hpp:26
Readiness predicate and optional targeted wakeup registration for a blocking wait.
Definition scheduler.hpp:133
WaitPredicate is_ready
Predicate that reports whether the requested value is available.
Definition scheduler.hpp:135
WaitWakeupRegistration notify_when_ready
Register a non-throwing wakeup, including when readiness races with registration.
Definition scheduler.hpp:142
Execution requirements used to validate a scheduler route.
Definition async_task.hpp:43