cplusplus / sender-receiver

Issues list for P2300
Apache License 2.0
18 stars 3 forks source link

Do we still plan to integrate p2257's design for a blocking query? #140

Open ericniebler opened 8 months ago

ericniebler commented 8 months ago

Issue by ericniebler Thursday Oct 28, 2021 at 21:00 GMT Originally opened as https://github.com/NVIDIA/stdexec/issues/225


http://wg21.link/p2257

ericniebler commented 8 months ago

Comment by kirkshoop Thursday Nov 25, 2021 at 05:46 GMT


This paper is fine. I had thought of using a set of independent cpos for each option (is_blocking(), is_inline()). That covers the same set of 4 scenarios but is much simpler.

is_inline | is_blocking | scenario false | false | thread pool false | true | fork/join true | false | non-blocking io true | true | blocking io

ericniebler commented 8 months ago

Comment by kirkshoop Thursday Nov 25, 2021 at 06:14 GMT


Same paper as #140

ericniebler commented 8 months ago

Comment by kirkshoop Wednesday Dec 08, 2021 at 23:00 GMT


I like the phrasing in P2257. Applied the wording in P2257 to cover the modified semantics of is_inline and is_blocking:

is_blocking()

is_inline()

In both cases there is no default value - if a sender does not specialize a query, then the sender makes no guarantees at all.

ericniebler commented 8 months ago

Comment by lewissbaker Saturday Dec 18, 2021 at 23:29 GMT


The is_blocking definition you've described here to me seems like a combination of:

A start() implementation that attempts to acquire a mutex, e.g. to add the op-state to a queue, might "block" even though it will not complete synchronously.

One thing that I would like to understand better is the use-case/motivation for when I would want to query is_blocking(). I can understand the use-case for completes_synchronously - I can place the op-state for such an operation on the stack rather than heap-allocate it (e.g. in submit()) or I can avoid synchronisation (e.g. in sync_wait()).

ericniebler commented 8 months ago

Comment by LeeHowes Tuesday Jan 11, 2022 at 00:05 GMT


So completes_sychronously is a fairly clear name for an optimisable case. It is fairly well-defined.

is_blocking is a correctness check. Async_scope.spawn_now might want to check that the passed sender is !is_blocking to be reasonably startable in an async environment. Really we want that to be forward progress guarantee specific, though.

Can we pass an FP guarantee here? is_blocking(execution::parallel, sender) and for any reasonably purposes we only define this for now for parallel agents. So if a parallel agent calls start() it will complete start. A weaker agent might not be allowed to call start at all, or it is undefined and we have the option of working out how to define that correctly for other agents later.

just(3) would probably be completes_sychronously==true but is_blocking == false for all FP guarantees.

ericniebler commented 8 months ago

Comment by ericniebler Friday Mar 10, 2023 at 23:55 GMT


It's time we start thinking hard about this issue again. Lots of related issues that a query (or two or three) might want to answer:

  1. Is this operation guaranteed to make forward progress if started on a [concurrent | parallel | weakly parallel] agent?
  2. Is this operation guaranteed to complete before start() returns? On this thread?
  3. Is this operation guaranteed to complete on the same scheduler it started on?

Others?

lewissbaker commented 1 month ago

This is currently triaged as P1 - is this something we can add later? Or are the ABI implications to doing so?

There might be some uses/dependencies on this in sync_wait() - enables optimizations that avoid synchronization.

It might also be useful/used by #269 - knowing if an operation can complete asynchronously or not can allow more efficient implementations of a "complete-inline-or-on-this-context" algorithm.