[exec.sysctxrepl] # 33 Execution control library [[exec]](./#exec) ## 33.16 Namespace system_context_replaceability [exec.sysctxrepl] ### [33.16.1](#general) General [[exec.sysctxrepl.general]](exec.sysctxrepl.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8432) Facilities in the system_context_replaceability namespace allow users to replace the default implementation of parallel_scheduler[.](#general-1.sentence-1) ### [33.16.2](#query) query_parallel_scheduler_backend [[exec.sysctxrepl.query]](exec.sysctxrepl.query) [🔗](#lib:query_parallel_scheduler_backend) `shared_ptr query_parallel_scheduler_backend(); ` [1](#query-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8443) query_parallel_scheduler_backend() returns the implementation object for a parallel scheduler[.](#query-1.sentence-1) [2](#query-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8447) *Returns*: A non-null shared pointer to an object that implements the parallel_scheduler_backend interface[.](#query-2.sentence-1) [3](#query-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8452) *Remarks*: This function is replaceable ([[dcl.fct.def.replace]](dcl.fct.def.replace#term.replaceable.function "9.6.5 Replaceable function definitions"))[.](#query-3.sentence-1) namespace std::execution::system_context_replaceability {struct [receiver_proxy](#lib:receiver_proxy "33.16.2 query_­parallel_­scheduler_­backend [exec.sysctxrepl.query]") {virtual ~receiver_proxy() = default; protected:virtual bool *query-env*(*unspecified*) noexcept = 0; // *exposition only*public:virtual void set_value() noexcept = 0; virtual void set_error(exception_ptr) noexcept = 0; virtual void set_stopped() noexcept = 0; template synopsis [execution.syn]") Query> optional

try_query(Query q) noexcept; }; struct [bulk_item_receiver_proxy](#lib:bulk_item_receiver_proxy "33.16.2 query_­parallel_­scheduler_­backend [exec.sysctxrepl.query]") : receiver_proxy {virtual void execute(size_t, size_t) noexcept = 0; };} [4](#query-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8480) receiver_proxy represents a receiver that will be notified by the implementations of parallel_scheduler_backend to trigger the completion operations[.](#query-4.sentence-1) bulk_item_receiver_proxy is derived from receiver_proxy and is used for bulk_chunked and bulk_unchunked customizations that will also receive notifications from implementations of parallel_scheduler_backend corresponding to different iterations[.](#query-4.sentence-2) [🔗](#query-itemdecl:2) `template synopsis [execution.syn]") Query> optional

[try_query](#lib:try_query "33.16.2 query_­parallel_­scheduler_­backend [exec.sysctxrepl.query]")(Query q) noexcept; ` [5](#query-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8497) *Mandates*: P is a cv-unqualified non-array object type[.](#query-5.sentence-1) [6](#query-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8501) *Returns*: Let env be the environment of the receiver represented by *this[.](#query-6.sentence-1) If - [(6.1)](#query-6.1) Query is not a member of an implementation-defined set of supported queries; or - [(6.2)](#query-6.2) P is not a member of an implementation-defined set of supported result types for Query; or - [(6.3)](#query-6.3) the expression q(env) is not well-formed or does not have type cv P, then returns nullopt[.](#query-6.sentence-2) Otherwise, returns q(env)[.](#query-6.sentence-3) [7](#query-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8519) *Remarks*: get_stop_token_t is in the implementation-defined set of supported queries, andinplace_stop_token is a member of the implementation-defined set of supported result types for get_stop_token_t[.](#query-7.sentence-1) ### [33.16.3](#psb) Class parallel_scheduler_backend [[exec.sysctxrepl.psb]](exec.sysctxrepl.psb) namespace std::execution::system_context_replaceability {struct [parallel_scheduler_backend](#lib:parallel_scheduler_backend "33.16.3 Class parallel_­scheduler_­backend [exec.sysctxrepl.psb]") {virtual ~parallel_scheduler_backend() = default; virtual void schedule(receiver_proxy&, span) noexcept = 0; virtual void schedule_bulk_chunked(size_t, bulk_item_receiver_proxy&, span) noexcept = 0; virtual void schedule_bulk_unchunked(size_t, bulk_item_receiver_proxy&, span) noexcept = 0; };} [🔗](#lib:schedule,parallel_scheduler_backend) `virtual void schedule(receiver_proxy& r, span s) noexcept = 0; ` [1](#psb-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8550) *Preconditions*: The ends of the lifetimes of *this, the object referred to by r, and any storage referenced by s all happen after the beginning of the evaluation of the call to set_value, set_error, or set_done on r (see below)[.](#psb-1.sentence-1) [2](#psb-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8561) *Effects*: A derived class shall implement this function such that: - [(2.1)](#psb-2.1) One of the following expressions is evaluated: * [(2.1.1)](#psb-2.1.1) r.set_value(), if no error occurs, and the work is successful; * [(2.1.2)](#psb-2.1.2) r.set_error(eptr), if an error occurs, where eptr is an object of type exception_ptr; * [(2.1.3)](#psb-2.1.3) r.set_stopped(), if the work is canceled[.](#psb-2.1.sentence-1) - [(2.2)](#psb-2.2) Any call to r.set_value() happens on an execution agent of the execution context represented by *this[.](#psb-2.2.sentence-1) [3](#psb-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8581) *Remarks*: The storage referenced by s may be used by *this as temporary storage for the duration of the operation launched by this call[.](#psb-3.sentence-1) [🔗](#lib:schedule_bulk_chunked,parallel_scheduler_backend) `virtual void schedule_bulk_chunked(size_t n, bulk_item_receiver_proxy& r, span s) noexcept = 0; ` [4](#psb-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8595) *Preconditions*: The ends of the lifetimes of *this, the object referred to by r, and any storage referenced by s all happen after the beginning of the evaluation of one of the expressions below[.](#psb-4.sentence-1) [5](#psb-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8604) *Effects*: A derived class shall implement this function such that: - [(5.1)](#psb-5.1) Eventually, one of the following expressions is evaluated: * [(5.1.1)](#psb-5.1.1) r.set_value(), if no error occurs, and the work is successful; * [(5.1.2)](#psb-5.1.2) r.set_error(eptr), if an error occurs, where eptr is an object of type exception_ptr; * [(5.1.3)](#psb-5.1.3) r.set_stopped(), if the work is canceled[.](#psb-5.1.sentence-1) - [(5.2)](#psb-5.2) If r.execute(b, e) is called, then b and e are in the range [0, n] andb < e[.](#psb-5.2.sentence-1) - [(5.3)](#psb-5.3) For each i in [0, n), there is at most one call to r.execute(b, e) such that i is in the range [b, e)[.](#psb-5.3.sentence-1) - [(5.4)](#psb-5.4) If r.set_value() is called, then for each i in [0, n), there is exactly one call to r.execute(b, e) such that i is in the range [b, e)[.](#psb-5.4.sentence-1) - [(5.5)](#psb-5.5) All calls to execute on r happen before the call to either set_value, set_error, or set_stopped on r[.](#psb-5.5.sentence-1) - [(5.6)](#psb-5.6) All calls to execute and set_value on r are made on execution agents of the execution context represented by *this[.](#psb-5.6.sentence-1) [6](#psb-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8641) *Remarks*: The storage referenced by s may be used by *this as temporary storage for the duration of the operation launched by this call[.](#psb-6.sentence-1) [🔗](#lib:schedule_bulk_unchunked,parallel_scheduler_backend) `virtual void schedule_bulk_unchunked(size_t n, bulk_item_receiver_proxy& r, span s) noexcept = 0; ` [7](#psb-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8654) *Preconditions*: The ends of the lifetimes of *this, the object referred to by r, and any storage referenced by s all happen after the beginning of the evaluation of one of the expressions below[.](#psb-7.sentence-1) [8](#psb-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8663) *Effects*: A derived class shall implement this function such that: - [(8.1)](#psb-8.1) Eventually, one of the following expressions is evaluated: * [(8.1.1)](#psb-8.1.1) r.set_value(), if no error occurs, and the work is successful; * [(8.1.2)](#psb-8.1.2) r.set_error(eptr), if an error occurs, where eptr is an object of type exception_ptr; * [(8.1.3)](#psb-8.1.3) r.set_stopped(), if the work is canceled[.](#psb-8.1.sentence-1) - [(8.2)](#psb-8.2) If r.execute(b, e) is called, then b is in the range [0, n) ande is equal to b + 1[.](#psb-8.2.sentence-1) For each i in [0, n), there is at most one call to r.execute(i, i + 1)[.](#psb-8.2.sentence-2) - [(8.3)](#psb-8.3) If r.set_value() is called, then for each i in [0, n), there is exactly one call to r.execute(i, i + 1)[.](#psb-8.3.sentence-1) - [(8.4)](#psb-8.4) All calls to execute on r happen before the call to either set_value, set_error, or set_stopped on r[.](#psb-8.4.sentence-1) - [(8.5)](#psb-8.5) All calls to execute and set_value on r are made on execution agents of the execution context represented by *this[.](#psb-8.5.sentence-1) [9](#psb-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8697) *Remarks*: The storage referenced by s may be used by *this as temporary storage for the duration of the operation launched by this call[.](#psb-9.sentence-1)