-
Notifications
You must be signed in to change notification settings - Fork 187
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
Reimplement scheduler affinity #527
Conversation
This depends on #526. |
23d1445
to
7bd7d60
Compare
To make this really work well, I'll need to follow up with customizations of |
7bd7d60
to
25aea72
Compare
// TODO: verify that `at_coroutine_exit()` can't be used to break scheduler | ||
// affinity by running an async task that reschedules |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at_coroutine_exit
can already break Scheduler affinity so this is a TODO, which I've captured in #535.
This diff changes how `unifex::task<>` implements *Scheduler* affinity to work more like `folly::coro::Task<>`. What Folly calls `co_viaIfAsync`, this diff calls `with_scheduler_affinity`, which is a new CPO. `with_scheduler_affinity` is a *Sender* algorithm that maps the given *Sender* to another *Sender* that must meet new postconditions if the *Receiver* that it's connected to meets certain preconditions. The new preconditions are: - the eventual *Receiver* must provide a "current *Scheduler*"; - the result of `with_scheduler_affinity` must be started on the *Receiver's* current *Scheduler*; and - stop requests delivered to the new *Sender* must be delivered on the *Receiver's* current *Scheduler*. The *Sender* returned from `with_scheduler_affinity` must complete on its *Receiver's* current *Scheduler* (i.e. must complete where it was started) so long as all the above preconditions are met. Any *Sender* type, `S`, that has `sender_traits<S>::is_always_scheduler_affine` set to `true` will be returned unmodified from `with_scheduler_affinity`. For *Senders* that are not always *Scheduler*-affine and that do not customize `with_scheduler_affinity`, the default implementation is: ``` template <typename Sender, typename Scheduler> auto with_scheduler_affinity(Sender&& s, Scheduler&& sched) { return finally( std::forward<Sender>(s), unstoppable(schedule(std::forward<Scheduler>(sched)))); } ```
include/unifex/task.hpp
Outdated
* nested stop source on the correct scheduler; and | ||
* - ensure that, if the async stop request is ever started, we wait for | ||
* *both* the async stop request *and* the nested operation to complete | ||
* before continuating our continuation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol, "continuating"
This diff address the review comments I left myself, other than the ones I punted to issues. I also realized I could use a `manual_lifetime<>` instead of a `std::optional<>` for the `_sr_thunk_task`'s stop callback, which saves a little overhead.
25aea72
to
e002af2
Compare
|
||
template <typename Sender, typename Scheduler> | ||
using wsa_sender_wrapper = | ||
typename _wsa_sender_wrapper<Sender, Scheduler>::type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: just _wsa_sender
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe next time I'm in here; I'd like to get this merged so we can sync it internally.
This diff changes how
unifex::task<>
implements Scheduler affinity to work more likefolly::coro::Task<>
. What Folly callsco_viaIfAsync
, this diff callswith_scheduler_affinity
, which is a new CPO.with_scheduler_affinity
is a Sender algorithm that maps the given Sender to another Sender that must meet new postconditions if the Receiver that it's connected to meets certain preconditions. The new preconditions are:with_scheduler_affinity
must be started on the Receiver's current Scheduler; andThe Sender returned from
with_scheduler_affinity
must complete on its Receiver's current Scheduler (i.e. must complete where it was started) so long as all the above preconditions are met.with_scheduler_affinity
has two default implementations for a Sender typeS
:sender_traits<S>::is_always_scheduler_affine
istrue
, the default is the identity;sender_traits<S>::is_always_scheduler_affine
isfalse
, the default is, essentially, atyped_via
back to the correct scheduler.Any Sender can customize
with_scheduler_affinity
, regardless of itsis_always_scheduler_affine
property.