Title
Reconsider `weakly_parallel` as the default `forward_progress_guarantee`
Status
new
Section
[exec.get.fwd.progress]
Submitter
Lewis Baker

Created on 2025-08-25.00:00:00 last changed 3 days ago

Messages

Date: 2025-09-14.10:34:01

Proposed resolution:

This wording is relative to N5014.

  1. Modify [exec.get.fwd.progress] as indicated:

    -2- The name `get_forward_progress_guarantee` denotes a query object. For a subexpression `sch`, let `Sch` be `decltype((sch))`. If `Sch` does not satisfy `scheduler`, `get_forward_progress_guarantee` is ill-formed. Otherwise, `get_forward_progress_guarantee(sch)` is expression-equivalent to:

    1. (2.1) — MANDATE-NOTHROW(AS-CONST(sch).query(get_forward_progress_guarantee)) if that expression is well-formed.

      Mandates: The type of the expression above is `forward_progress_guarantee`.

    2. (2.2) — Otherwise, forward_progress_guarantee::weakly_parallel.

Date: 2025-08-25.00:00:00

The `get_forward_progress_guarantee` CPO is intended to allow querying a scheduler as for what sort of forward-progress guarantee it provides. Algorithms may use this to determine whether it is safe to execute certain operations on a given scheduler. If a scheduler does not customize this query, the query will fall back to returning a forward-progress guarantee of weakly_parallel.

I think we should reconsider what this default should be returning and suggest it should instead return `parallel` by default, as this will be by far the most common kind of scheduler, i.e. a scheduler that executes on `std::thread`-like execution agents and that maintains a queue of scheduled tasks.

I expect it to be common that authors of schedulers may forget to customize the `get_forward_progress_guarantee_t` query and just leave it at the default. This will likely leave their scheduler reporting a weaker guarantee than it actually provides and thus not being usable within generic algorithms that require at least parallel forward progress.

For example, the `run_loop` execution context defined in [exec.run.loop] does not define its scheduler to customize the `get_forward_progress_guarantee_t`. This means it will report the default value of `weakly_parallel`.

However, the scheduled operations will run on the thread that calls `run_loop::run()` and thus will inherit its forward-progress guarantees. As this function might block and is therefore unsafe to invoke it from a thread/agent with `weakly_parallel` forward progress guarantees (which should probably be explicitly specified as having undefined-behaviour) we can safely assume that `run_loop`'s scheduler can provide parallel forward-progress guarantee.

It's not clear whether the current `run_loop` specification defaulting to its scheduler having `weakly_parallel` forward progress guarantee is intentional or unintentional here. However, forgetting to define the `get_forward_progress_guarantee` query on a scheduler is something I expect to be fairly common.

Schedulers that provide `weakly_parallel` (or in future, `concurrent`) forward progress guarantees require implementations to be much more aware of the fact that these are the guarantees they are providing and thus could be more expected to customize the `get_forward_progress_guarantee` query to return the respective values.

History
Date User Action Args
2025-09-14 10:34:01adminsetmessages: + msg15024
2025-08-25 00:00:00admincreate