<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.12: http://docutils.sourceforge.net/" />
<title>P0737r0 : Execution Context of Execution Agents</title>
<meta name="date" content="2017-10-11" />
<meta name="author" content="H. Carter Edwards, Sandia National Laboratories" />
<meta name="author" content="Daniel Sunderland, Sandia National Laboratories" />
<meta name="author" content="Michael Wong, Codeplay" />
<meta name="author" content="Thomas Rodgers" />
<meta name="author" content="Gordon Brown, Codeplay" />
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="p0737r0-execution-context-of-execution-agents">
<h1 class="title">P0737r0 : Execution Context of Execution Agents</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">Project:</th><td class="field-body">ISO JTC1/SC22/WG21: Programming Language C++</td>
</tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">P0737r0</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2017-10-11</td></tr>
<tr class="field"><th class="docinfo-name">Reply-to:</th><td class="field-body"><a class="reference external" href="mailto:hcedwar&#64;sandia.gov">hcedwar&#64;sandia.gov</a></td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>H. Carter Edwards, Sandia National Laboratories</td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Daniel Sunderland, Sandia National Laboratories</td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Michael Wong, Codeplay</td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Thomas Rodgers</td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Gordon Brown, Codeplay</td></tr>
<tr class="field"><th class="docinfo-name">Audience:</th><td class="field-body">SG1 Concurrency and Parallelism</td>
</tr>
<tr class="field"><th class="docinfo-name">URL:</th><td class="field-body"><a class="reference external" href="https://github.com/kokkos/ISO-CPP-Papers/blob/master/P0737_ExecContext.rst">https://github.com/kokkos/ISO-CPP-Papers/blob/master/P0737_ExecContext.rst</a></td>
</tr>
</tbody>
</table>
<div class="section" id="revision-history">
<h1>Revision History</h1>
<div class="section" id="d0737r0-for-2017-11-albuquerque-pre-meeting-mailing">
<h2>D0737r0 : For 2017-11-Albuquerque pre-meeting mailing</h2>
<blockquote>
<ul class="simple">
<li>State: Design exploration</li>
<li>Requested straw polls:<ul>
<li>Proposed definition of ExecutionContext <em>concept</em><ul>
<li>Non-copyable and non-moveable</li>
<li>Execution resource</li>
<li>Wait functions</li>
<li>Executor generator</li>
<li>Query property</li>
<li>Destructor behavior</li>
</ul>
</li>
<li>Proposed thread execution resource</li>
<li>Proposed this_thread query of thread execution resource</li>
<li>Proposed standard async execution context and executor</li>
<li>Interest in each of the suggested <a class="reference internal" href="#potential-additions">potential additions</a>
for initial insertion into Concurrency or Executors TS</li>
</ul>
</li>
</ul>
</blockquote>
</div>
</div>
<div class="section" id="the-problem">
<h1>The Problem</h1>
<p>Current Executor proposal does not define a specific concrete context.
An Execution Context is meant to mediate between Execution agents,
an executor, and execution resources.
Specifically, an execution context is responsible for
managing the execution of a number of (light-weight) execution agents
on an execution resource.
An execution context also provides executors for submitting work to itself.</p>
<p>The Executor proposal currently does not specifically define a
concrete execution context, other then providing a static thread pool
as a basic example.
As the executor proposal is a joint proposal between several
industry representatives - parallel and vectorized algorithms,
multi-threaded execution, heterogeneous and distributed execution,
and network execution.
It was not deemed necessary to provide a specific concrete execution context.
For some areas, a concrete execution context is necessary because
it could be used to manage a stream or queue of command kernels,
such as in heterogeneous or distributed computing.
In other domains, such as parallel aand vectorized algorithms,
it may remain an abstract concept.</p>
<p>This paper focuses on those domains where a concrete Execution Context
is extermemly important while also proposing a mechanism for defining
the system affinity.</p>
<p>Another area of interest that can be supported by Context
is the querying of the memory affinity status of the system.
This is important as a concept to enable future support for
affinity (see the Affinity paper). This is an area that
requires solution and this papers outlines one such direction.</p>
</div>
<div class="section" id="proposal">
<h1>Proposal</h1>
<p>Add this minimal ExecutionContext specification to the Executors TS.</p>
<div class="section" id="concept-definition">
<h2>Concept / Definition</h2>
<p>A concurrency and parallelism <strong>execution context</strong> manages a set of
execution agents on a set of <strong>execution resources</strong> of a given
<strong>execution architecture</strong>.
These execution agents execute work, implemented by a callable,
that is submitted to the execution context by an <strong>executor</strong>.
One or more types of executors may submit work to the same
execution context.
Work submitted to an execution context is <strong>incomplete</strong> until
(1) it is invoked and exits execution by return or exception or
(2) its submission for execution is cancelled.</p>
<blockquote>
Note: The <em>execution context</em> terminology used here
and in the Networking TS (N4656) deviate from the
traditional <em>context of execution</em> usage that refers
to the state of a single executing callable; <em>e.g.</em>,
program counter, registers, stack frame.</blockquote>
</div>
<div class="section" id="contrast-to-networking-ts-n4656-execution-context">
<h2>Contrast to Networking TS (N4656) Execution Context</h2>
<p>The Networking TS (N4656 / 2017-03-17) defines a
<em>networking execution context</em> as</p>
<blockquote>
&quot;Class <tt class="docutils literal">execution_context</tt> implements an extensible, type-safe,
polymorphic set of services, indexed by service type.&quot;</blockquote>
<p>The networking TS requirements for <tt class="docutils literal">execution_context</tt>
specify a single <tt class="docutils literal"><span class="pre">execution_context::executor_type</span></tt>.
This executor type has numerous work submission member functions
each with particular semantics.</p>
<p>Differences between our proposed parallelism and concurrency execution context
and the networking execution context include the following.</p>
<blockquote>
<ol class="arabic simple">
<li>Networking context is Limited to executing work, as opposed to providing unspecified services.</li>
<li>Networking context is not a concrete base class from which other forms of execution contexts
are derived; <em>e.g.</em>, <tt class="docutils literal">system_context</tt> , <tt class="docutils literal">io_context</tt> .</li>
<li>Our context is an extensible one-to-many relationship between an execution context type
and executor types that may submit work, as opposed to a particular
executor type with specific work submission functions.</li>
<li>Our proposed <tt class="docutils literal">async_execution_context</tt> could be viewed as having
similar intent as the networking <tt class="docutils literal">system_context</tt>.
The significant difference is interchangeability with
<tt class="docutils literal"><span class="pre">std::async</span></tt> usage and extensibility to other executors
versus the prescribed networking <tt class="docutils literal">system_executor</tt>.</li>
</ol>
</blockquote>
</div>
<div class="section" id="partitioning-and-affinity-state-of-the-art">
<h2>Partitioning and Affinity State of the Art</h2>
<div class="section" id="hardware-locality-hwloc-software-package">
<h3>Hardware Locality (hwloc) Software Package</h3>
<p>The <a class="reference external" href="https://www.open-mpi.org/projects/hwloc/">hardware locality (hwloc) software package</a>
provides a portable interface for querying and managing
hardware resources, including <em>processing units</em>
on which threads execute.
The proposed thread execution resource is motivated
by a small fraction of hwloc capabilities.</p>
</div>
<div class="section" id="sycl-for-opencl-and-hsa">
<h3>SYCL for OpenCL and HSA</h3>
<p><a class="reference external" href="https://www.khronos.org/registry/SYCL/specs/sycl-1.2.pdf">SYCL</a> (based on
<a class="reference external" href="https://www.khronos.org/registry/OpenCL/specs/opencl-2.2.pdf">OpenCL</a>)
provides a C++ programming model for targeting a wide range of heterogeneous
systems including multi-core CPUs, NUMA systems, embedded SoCs and discrete
accelerators.
<a class="reference external" href="http://www.hsafoundation.com/standards/">HSA (Heterogeneous System Architecture)</a>
is a similar standard that provides a lower level, and lower overhead API and
set of architecture requirements.</p>
<p>Both of these standards represent the topology of a system with a hierarchy of
ids that remain constant throughout the execution of a program. Both also allow
users to partition the system topology to do fine-grained work execution. The
extent of the partitioning depends on the platform.</p>
</div>
<div class="section" id="openmp">
<h3>OpenMP</h3>
<p>In contrast, OpenMP requires an external environment variable set by the user.
They use the idea of an abstract Place as defined by the user over all threads, cores, and sockets.
In this way, it enable the user to secify the granularity of the topology, and then further enable
defining the desired affinity for being on the same Place as master thread, or scatter out in a round robin fashion,
as well as compacting it around the Master. It can also define for each nested parallelism level,
because the work may change or become irregular during runtime.</p>
<p>This design, while flexible is not possible for C++ Affinty. C++ cannot use the environment variable for input configuration.
The advantage of the OpenMP design is its use of abstract places which makes it flexible for some future core configuration
but it means the programmer has to decide whether to describe the places
in terms of threads, cores, or sockets which still requires some actual hardware knowledge.
Still, the fundamental of its implementation has shown it is doable on most architectures. In that respect, C++ implementation
would only need to define the interface, but the underlying mechanism should be similar.
Since its addition in OpenMP 3, this feature has a great deal of experience from HPC and demonstartes implementability.</p>
</div>
</div>
<div class="section" id="minimal-concept-specification">
<h2>Minimal <em>Concept</em> Specification</h2>
<blockquote>
The proposed <em>parallelism and concurrency execution context</em>
has minimal scope, with the intent to grow this scope as
consensus is achieved on <a class="reference internal" href="#potential-additions">potential additions</a>.</blockquote>
<pre class="code c++ literal-block">
<span class="keyword">class</span> <span class="name class">ExecutionContext</span> <span class="comment multiline">/* exposition only */</span> <span class="punctuation">{</span>
<span class="keyword">public</span><span class="operator">:</span>

  <span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span> <span class="name">ExecutionContextProperty</span><span class="operator">&gt;</span>
    <span class="comment multiline">/* exposition only */</span> <span class="name">detail</span><span class="operator">::</span><span class="keyword type">query_t</span><span class="operator">&lt;</span> <span class="name">ExecutionContext</span> <span class="punctuation">,</span> <span class="name">ExecutionContextProperty</span> <span class="operator">&gt;</span>
  <span class="name">query</span><span class="punctuation">(</span><span class="name">ExecutionContextProperty</span> <span class="name">p</span><span class="punctuation">)</span> <span class="keyword">const</span> <span class="punctuation">;</span>

  <span class="operator">~</span><span class="name">ExecutionContext</span><span class="punctuation">();</span>

  <span class="comment single">// Not copyable or moveable
</span>  <span class="name">ExecutionContext</span><span class="punctuation">(</span> <span class="name">ExecutionContext</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="name">ExecutionContext</span><span class="punctuation">(</span> <span class="name">ExecutionContext</span> <span class="operator">&amp;&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="name">ExecutionContext</span> <span class="operator">&amp;</span> <span class="keyword">operator</span> <span class="operator">=</span> <span class="punctuation">(</span> <span class="name">ExecutionContext</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="name">ExecutionContext</span> <span class="operator">&amp;</span> <span class="keyword">operator</span> <span class="operator">=</span> <span class="punctuation">(</span> <span class="name">ExecutionContext</span> <span class="operator">&amp;&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>

  <span class="comment single">// Execution resource
</span>  <span class="keyword">using</span> <span class="keyword type">execution_resource_t</span> <span class="operator">=</span> <span class="comment multiline">/* implementation defined */</span> <span class="punctuation">;</span>

  <span class="keyword type">execution_resource_t</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">execution_resource</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="comment single">// Executor generator
</span>  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">ExecutorProperties</span> <span class="operator">&gt;</span>
    <span class="comment multiline">/* exposition only */</span> <span class="name">detail</span><span class="operator">::</span><span class="keyword type">executor_t</span><span class="operator">&lt;</span> <span class="name">ExecutionContext</span> <span class="punctuation">,</span> <span class="name">ExecutorProperties</span><span class="punctuation">...</span> <span class="operator">&gt;</span>
  <span class="name">executor</span><span class="punctuation">(</span> <span class="name">ExecutorProperties</span><span class="punctuation">...</span> <span class="punctuation">);</span>

  <span class="comment single">// Waiting functions:
</span>  <span class="keyword type">void</span> <span class="name function">wait</span><span class="punctuation">();</span>
  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="name class">Clock</span> <span class="punctuation">,</span> <span class="keyword">class</span> <span class="name class">Duration</span> <span class="operator">&gt;</span>
  <span class="keyword type">bool</span> <span class="name">wait_until</span><span class="punctuation">(</span> <span class="name">chrono</span><span class="operator">::</span><span class="name">time_point</span><span class="operator">&lt;</span><span class="name">Clock</span><span class="punctuation">,</span><span class="name">Duration</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">);</span>
  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="name class">Rep</span> <span class="punctuation">,</span> <span class="keyword">class</span> <span class="name class">Period</span> <span class="operator">&gt;</span>
  <span class="keyword type">bool</span> <span class="name">wait_for</span><span class="punctuation">(</span> <span class="name">chrono</span><span class="operator">::</span><span class="name">duration</span><span class="operator">&lt;</span><span class="name">Rep</span><span class="punctuation">,</span><span class="name">Period</span><span class="operator">&gt;</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">);</span>
<span class="punctuation">};</span>

<span class="keyword type">bool</span> <span class="keyword">operator</span> <span class="operator">==</span> <span class="punctuation">(</span> <span class="name">ExecutionContext</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">,</span> <span class="name">ExecutionContext</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">);</span>
<span class="keyword type">bool</span> <span class="keyword">operator</span> <span class="operator">!=</span> <span class="punctuation">(</span> <span class="name">ExecutionContext</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">,</span> <span class="name">ExecutionContext</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">);</span>

<span class="comment single">// Execution context properties:
</span>
<span class="keyword">constexpr</span> <span class="keyword">struct</span> <span class="keyword type">reject_on_destruction_t</span> <span class="punctuation">{}</span> <span class="name">reject_on_destruction</span><span class="punctuation">;</span>
<span class="keyword">constexpr</span> <span class="keyword">struct</span> <span class="keyword type">abandon_on_destruction_t</span> <span class="punctuation">{}</span> <span class="name">abandon_on_destruction</span><span class="punctuation">;</span>
<span class="keyword">constexpr</span> <span class="keyword">struct</span> <span class="keyword type">abort_on_destruction_t</span> <span class="punctuation">{}</span> <span class="name">abort_on_destruction</span><span class="punctuation">;</span>
<span class="keyword">constexpr</span> <span class="keyword">struct</span> <span class="keyword type">wait_on_destruction_t</span> <span class="punctuation">{}</span> <span class="name">wait_on_destruction</span><span class="punctuation">;</span>
</pre>
<!--  -->
<p>Let <tt class="docutils literal">EC</tt> be an <em>ExecutionContext</em> type.</p>
<div class="line-block">
<div class="line"><tt class="docutils literal">template &lt;typename ExecutionContextProperty&gt;</tt></div>
<div class="line-block">
<div class="line"><tt class="docutils literal">/* exposition only */ <span class="pre">detail::query_t&lt;</span> EC , ExecutionContextProperty &gt;</tt></div>
</div>
<div class="line"><tt class="docutils literal"><span class="pre">EC::query(ExecutionContextProperty</span> p) const noexcept;</tt></div>
</div>
<blockquote>
<p>Requires:
<tt class="docutils literal">ExecutionContextProperty</tt> is an execution context property.</p>
<p>Returns:
The current value of the execution context property specified by <tt class="docutils literal">p</tt>
when the execution context supports the input property.
Otherwise <tt class="docutils literal">void</tt>.
[Note: The <em>detail::query_t</em> is for exposition only denoting the
expectation that an implementation will use an implementation-defined
metafunction to determine the return type. --end note]</p>
<p>Remark:
When <tt class="docutils literal">is_same_v&lt;void,decltype(ec.query(p))</tt> then the execution context
property is unknown to the execution context.</p>
</blockquote>
<p><tt class="docutils literal"><span class="pre">EC::execution_resource_t</span> const &amp; <span class="pre">EC::execution_resource()</span> const noexcept ;</tt></p>
<blockquote>
Returns: A descriptor of the execution resource(s) utilized by this
execution context to execute work.
Execution architecture is identified by the <tt class="docutils literal">execution_resource_t</tt> type.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class ... ExecutorProperties &gt;</tt></div>
<div class="line-block">
<div class="line"><tt class="docutils literal">/* exposition only */ <span class="pre">detail::executor_t&lt;</span> EC , <span class="pre">ExecutorProperties...</span> &gt;</tt></div>
</div>
<div class="line"><tt class="docutils literal"><span class="pre">EC::executor(</span> ExecutorProperties ... p );</tt></div>
</div>
<blockquote>
Returns:
An executor with <tt class="docutils literal">*this</tt> execution context and
execution properties <tt class="docutils literal">p</tt> when the execution context
supports these properties.
Otherwise <tt class="docutils literal">void</tt>.
[Note: The <em>detail::executor_t</em> is for exposition only denoting the
expectation that an implementation will use an implementation-defined
metafunction to determine the type of the returned executor. --end note]</blockquote>
<pre class="code c++ literal-block">
<span class="keyword">static_assert</span><span class="punctuation">(</span> <span class="operator">!</span> <span class="name">is_same_v</span><span class="operator">&lt;</span> <span class="keyword type">void</span> <span class="punctuation">,</span> <span class="keyword">decltype</span><span class="punctuation">(</span> <span class="name">ec</span><span class="punctuation">.</span><span class="name">executor</span><span class="punctuation">(</span> <span class="name">p</span><span class="punctuation">...</span> <span class="punctuation">)</span> <span class="punctuation">)</span>
             <span class="punctuation">,</span> <span class="literal string">&quot;Execution context cannot generate executor for given executor properties.&quot;</span> <span class="punctuation">);</span>
</pre>
<!--  -->
<blockquote>
Remark:
A particular execution property may have semantic and interface implications,
such as whether application of the exector returns a future or not
(sometimes referred to as a two-way or one-way property).
A particular execution property may only be a performance hint.</blockquote>
<p><tt class="docutils literal">void <span class="pre">EC::wait();</span></tt></p>
<blockquote>
<p>Requires:
Cannot be called from non-blocking work submitted to this execution context.
[Note: Work waiting upon itself guarantees deadlock. --end note]</p>
<p>Effects:
Waits until the number of incomplete, non-blocking callables submitted
to the execution context is observed to be zero.
[Note: The execution agent from which the wait function is called should
<em>boost block</em> execution agents in the execution context. --end note]</p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class Clock , class Duration &gt;</tt></div>
<div class="line"><tt class="docutils literal">bool <span class="pre">EC::wait_until(</span> <span class="pre">chrono::time_point&lt;Clock,Duration&gt;</span> const &amp; dt );</tt></div>
<div class="line"><tt class="docutils literal">template&lt; class Rep , class Period &gt;</tt></div>
<div class="line"><tt class="docutils literal">bool <span class="pre">EC::wait_for(</span> <span class="pre">chrono::duration&lt;Rep,Period&gt;</span> const &amp; dt );</tt></div>
</div>
<blockquote>
<p>Requires:
Cannot be called from non-blocking work submitted to this execution context.
[Note: Work waiting upon itself can never return true. --end note]</p>
<p>Returns:
<tt class="docutils literal">true</tt> if the number of incomplete callables is observed zero
at any point during the call to wait.</p>
<p>Effects:
Waits at least <tt class="docutils literal">dt</tt> for the number of incomplete, non-blocking
callables submitted to the execution context is observed to be zero.
[Note: The execution agent from which the wait function is called should
<em>boost block</em> execution agents in the execution context, but may
only poll to honor the time out.  --end note]</p>
</blockquote>
<p><tt class="docutils literal"><span class="pre">EC::~EC();</span></tt></p>
<blockquote>
<p>Effects:
Behavior during destruction is denoted by the values of the queried
execution context properties.</p>
<blockquote>
<ul class="simple">
<li>If <tt class="docutils literal"><span class="pre">EC::query(reject_on_destruction)</span></tt> returns true
then submission of any new work to <tt class="docutils literal">*this</tt> is rejected.</li>
<li>If <tt class="docutils literal"><span class="pre">EC::query(abandon_on_destruction)</span></tt> returns true
then work that has been submitted to <tt class="docutils literal">*this</tt>
but has not yet started executing is abandoned and
submission of any new work to <tt class="docutils literal">*this</tt> is rejected.</li>
<li>If <tt class="docutils literal"><span class="pre">EC::query(wait_on_destruction)</span></tt> returns true
then <tt class="docutils literal">*this</tt> destructor blocks until work that is executing,
not rejected, or not abandoned has completed.</li>
<li>If <tt class="docutils literal"><span class="pre">EC::query(abort_on_destruction)</span></tt> returns true
then <tt class="docutils literal">*this</tt> attempts to abort work that is executing,
abandons work that has not yet started executing,
rejects submission of any new work, and does not block.
It may not be feasible to abort executing work; however,
such work will cease to have a defined execution context.</li>
</ul>
</blockquote>
<p>Remark:
For example, if
<tt class="docutils literal"><span class="pre">EC::query(reject_on_destruction)</span></tt>,
<tt class="docutils literal"><span class="pre">!EC::query(abandon_on_destruction)</span></tt>, and
<tt class="docutils literal"><span class="pre">EC::query(wait_on_destruction)</span></tt> then
submission of new work is rejected and the destructor blocks
until all executing and previously submitted work completes.</p>
</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">bool operator == ( EC const &amp; lhs , EC const &amp; rhs );</tt></div>
<div class="line"><tt class="docutils literal">bool operator != ( EC const &amp; lhs , EC const &amp; rhs );</tt></div>
</div>
<blockquote>
Effects:
Return whether <tt class="docutils literal">lhs</tt> and <tt class="docutils literal">rhs</tt> refer (or not)
to the same execution context: submitting work to
<tt class="docutils literal">lhs</tt> has identical effect as submitting work to <tt class="docutils literal">rhs</tt>.</blockquote>
</div>
<div class="section" id="execution-resource-see-also-p0761-executors-design-document">
<h2>Execution Resource (see also P0761, Executors Design Document)</h2>
<p>An <em>execution resource</em> is an descriptor for an implementation defined
hardware and/or software facility capable of executing a
callable function object.
Different resources may offer a broad array of functionality
and semantics and exhibit different performance characteristics
of interest to the performance-conscious programmer.
For example, an implementation might expose different processor cores,
with potentially non-uniform access to memory, as separate resources
to enable programmers to reason about locality.</p>
<p>An execution resource can range from SIMD vector units accessible
in a single thread to an entire runtime managing a large collection of threads.</p>
</div>
<div class="section" id="thread-execution-resource">
<h2>Thread Execution Resource</h2>
<p>A <em>thread of execution</em> executes on a <em>processing unit</em> (PU) within an
<em>execution resource</em>.
<em>Threads of execution</em> can make <em>concurrent forward progress</em>
only if they execute on different processing units.
Conversely, a single processing unit cannot
cause two or more <em>threads of execution</em> to make concurrent forward progress.
A <em>thread execution resource</em> is associated with a
specific set of processing units within the system hardware.</p>
<blockquote>
[Note:
A <em>CPU hyperthread</em> is a common example of
a processing unit.
In a Linux runtime a <em>thread execution resource</em> is defined by
a <tt class="docutils literal">cpu_set_t</tt> object and is queried through the
<tt class="docutils literal">sched_getaffinity</tt> function.
--end note]</blockquote>
<p>A <em>processing unit</em> or <em>thread execution resource</em> may be what
was intended by the undefined term &quot;thread contexts&quot; in 33.3.2.6,
&quot;thread static members.&quot;</p>
<p>A <em>thread execution resource</em> may have <em>locality partitions</em>
for its associated set of processing units.
For example, hyperthreads sharing the same CPU core are more local
to one another than to a hyperthreads on different core.</p>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="keyword type">thread_execution_resource_t</span> <span class="punctuation">{</span>

  <span class="keyword type">thread_execution_resource_t</span><span class="punctuation">()</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="keyword type">thread_execution_resource_t</span><span class="punctuation">(</span> <span class="keyword type">thread_execution_resource_t</span> <span class="operator">&amp;&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="keyword type">thread_execution_resource_t</span><span class="punctuation">(</span> <span class="keyword type">thread_execution_resource_t</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="keyword type">thread_execution_resource_t</span> <span class="operator">&amp;</span> <span class="keyword">operator</span><span class="operator">=</span><span class="punctuation">(</span> <span class="keyword type">thread_execution_resource_t</span> <span class="operator">&amp;&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="keyword type">thread_execution_resource_t</span> <span class="operator">&amp;</span> <span class="keyword">operator</span><span class="operator">=</span><span class="punctuation">(</span> <span class="keyword type">thread_execution_resource_t</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>

  <span class="keyword type">size_t</span> <span class="name">concurrency</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="keyword type">size_t</span> <span class="name">partition_size</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="keyword">const</span> <span class="keyword type">thread_execution_resource_t</span> <span class="operator">&amp;</span> <span class="name">partition</span><span class="punctuation">(</span> <span class="keyword type">size_t</span> <span class="name">i</span> <span class="punctuation">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>

  <span class="keyword">const</span> <span class="keyword type">thread_execution_resource_t</span> <span class="operator">&amp;</span> <span class="name">member_of</span><span class="punctuation">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>
<span class="punctuation">};</span>

<span class="keyword">extern</span> <span class="keyword type">thread_execution_resource_t</span> <span class="name">program_thread_execution_resource</span> <span class="punctuation">;</span>
</pre>
<!--  -->
<p><tt class="docutils literal">size_t <span class="pre">concurrency();</span></tt></p>
<blockquote>
<p>Returns:
This execution resource's potential for concurrent forward progress;
<em>i.e.</em>, the number of processing units
associated with this execution resource.</p>
<p>Remark: Has similar intent as 33.2.2.6
<tt class="docutils literal"><span class="pre">std::thread::hardware_concurrency();</span></tt> which returns
&quot;The number of hardware thread contexts.&quot;</p>
</blockquote>
<p><tt class="docutils literal">size_t partition_size() const noexcept ;</tt></p>
<blockquote>
Returns:
Number of locality partitionings of the execution resource.</blockquote>
<p><tt class="docutils literal">const thread_execution_resource_t &amp; partition(size_t i) const noexcept ;</tt></p>
<blockquote>
<p>Requires: <tt class="docutils literal">i &lt; partition_size()</tt>.</p>
<p>Returns:
A locality partition of the execution resource.
Locality partitions are associated disjoint subsets of the
thread execution resource's processing units.</p>
</blockquote>
<pre class="code c++ literal-block">
<span class="keyword type">void</span> <span class="name function">verify_concurrency</span><span class="punctuation">(</span> <span class="keyword type">thread_execution_resource_t</span> <span class="keyword">const</span> <span class="operator">&amp;</span> <span class="name">E</span> <span class="punctuation">)</span>
<span class="punctuation">{</span>
  <span class="keyword type">size_t</span> <span class="name">sum</span> <span class="operator">=</span> <span class="literal number integer">0</span> <span class="punctuation">;</span>
  <span class="keyword">for</span> <span class="punctuation">(</span> <span class="keyword type">size_t</span> <span class="name">i</span> <span class="operator">=</span> <span class="literal number integer">0</span> <span class="punctuation">;</span> <span class="name">i</span> <span class="operator">&lt;</span> <span class="name">E</span><span class="punctuation">.</span><span class="name">partition_size</span><span class="punctuation">()</span> <span class="punctuation">;</span> <span class="operator">++</span><span class="name">i</span> <span class="punctuation">)</span>
    <span class="name">sum</span> <span class="operator">+=</span> <span class="name">E</span><span class="punctuation">.</span><span class="name">partition</span><span class="punctuation">(</span><span class="name">i</span><span class="punctuation">).</span><span class="name">concurrency</span><span class="punctuation">();</span>
  <span class="name">assert</span><span class="punctuation">(</span> <span class="name">E</span><span class="punctuation">.</span><span class="name">partition_size</span><span class="punctuation">()</span> <span class="operator">==</span> <span class="literal number integer">0</span> <span class="operator">||</span> <span class="name">E</span><span class="punctuation">.</span><span class="name">concurrency</span><span class="punctuation">()</span> <span class="operator">==</span> <span class="name">sum</span> <span class="punctuation">);</span>
<span class="punctuation">}</span>
</pre>
<!--  -->
<blockquote>
Remark:
Processing units residing in the same locality partition
are <em>more local</em> with respect to the memory system
than processing units in disjoint partitions.
For example, non-uniform memory access (NUMA) partitions.</blockquote>
<p><tt class="docutils literal">const thread_execution_resource_t &amp; member_of() const noexcept ;</tt></p>
<blockquote>
Returns:
If thread execution resource <tt class="docutils literal">M</tt> is a member of a
thread execution resource <tt class="docutils literal">E</tt> partitioning then returns <tt class="docutils literal">E</tt>,
<tt class="docutils literal">M == E.partition(i)</tt> for some <tt class="docutils literal">i</tt> then <tt class="docutils literal">E == M.member_of()</tt>.
Otherwise returns <tt class="docutils literal">M</tt>.</blockquote>
<p><tt class="docutils literal">extern thread_execution_resource_t program_thread_execution_resource ;</tt></p>
<blockquote>
<p>Thread execution resource in which the program is <em>permitted</em>
to execute threads.
When a program executes it is common for the system runtime to restrict
that program to execute on a subset of all possible processing units
of the system hardware.</p>
<blockquote>
[Note:
For example, the linux <tt class="docutils literal">taskset</tt> command can restrict a program to
a specified set of processing units.  The program can use
<tt class="docutils literal"><span class="pre">sched_getaffinity(0,...)</span></tt> to query that restriction.
The proposed <tt class="docutils literal">program_thread_execution_resource</tt>
is intended to provide the same information.
--end note]</blockquote>
<p>Requires:
<tt class="docutils literal">program_thread_execution_resource.member_of() ==
program_thread_execution_resource</tt> and all <tt class="docutils literal">member_of()</tt>
recursions terminate with <tt class="docutils literal">program_thread_execution_resource</tt>.</p>
<p>Remark:
A high-quality implementation will provide a hierarchical
locality partitioning that terminates when members have
<tt class="docutils literal">concurrency() == 1</tt>.</p>
</blockquote>
</div>
<div class="section" id="this-thread-execution-resource">
<h2>This Thread Execution Resource</h2>
<p>Add to <strong>33.3.3 Namespace this_thread</strong></p>
<pre class="code c++ literal-block">
<span class="keyword">namespace</span> <span class="name">std</span><span class="operator">::</span><span class="name">this_thread</span> <span class="punctuation">{</span>

  <span class="keyword">const</span> <span class="keyword type">thread_execution_resource_t</span> <span class="operator">&amp;</span> <span class="name">get_resource</span><span class="punctuation">();</span>

<span class="punctuation">}</span>
</pre>
<!--  -->
<p><tt class="docutils literal">const thread_execution_resource_t &amp; <span class="pre">this_thread::get_resource()</span></tt></p>
<blockquote>
<p>Returns:
An execution resource on which this thread was executing during the
call to <tt class="docutils literal">get_resource</tt>.</p>
<p>Remark:
A thread may migrate between thread execution resources.
As such the <tt class="docutils literal">get_resource</tt> returns one of those resources on
which the thread was executing during the call to <tt class="docutils literal">get_resource</tt>.
There is no guarantee that this thread is executing on the
returned thread execution resource before or after the
call to <tt class="docutils literal">get_resource</tt>.
A high-quality implementation will return an execution resource
with <tt class="docutils literal">concurrency() == 1</tt>.</p>
</blockquote>
</div>
<div class="section" id="motivation-for-standard-async-execution-context-and-executor">
<h2>Motivation for Standard Async Execution Context and Executor</h2>
<p>Require that the <strong>33.6.9 Function template async</strong>
have an equivalent execution context and executor based
mechanism for launching asynchronous work.
This exposes the currently hidden execution context and executor(s)
which the underlying runtime has implemented to enable <tt class="docutils literal"><span class="pre">std::async</span></tt>.</p>
<pre class="code c++ literal-block">
<span class="comment single">// Equivalent without- and with-executor async statements without launch policy
</span>
<span class="keyword">auto</span> <span class="name">f</span> <span class="operator">=</span> <span class="name">std</span><span class="operator">::</span><span class="name">async</span><span class="punctuation">(</span> <span class="punctuation">[]{</span> <span class="name">std</span><span class="operator">::</span><span class="name">cout</span> <span class="operator">&lt;&lt;</span> <span class="literal string">&quot;anonymous way</span><span class="literal string escape">\n</span><span class="literal string">&quot;</span><span class="punctuation">}</span> <span class="punctuation">);</span>
<span class="keyword">auto</span> <span class="name">f</span> <span class="operator">=</span> <span class="name">std</span><span class="operator">::</span><span class="name">async</span><span class="punctuation">(</span> <span class="name">std</span><span class="operator">::</span><span class="name">async_execution_context</span><span class="punctuation">.</span><span class="name">executor</span><span class="punctuation">()</span> <span class="punctuation">,</span> <span class="punctuation">[]{</span> <span class="name">std</span><span class="operator">::</span><span class="name">cout</span> <span class="operator">&lt;&lt;</span> <span class="literal string">&quot;executor way</span><span class="literal string escape">\n</span><span class="literal string">&quot;</span><span class="punctuation">}</span> <span class="punctuation">);</span>

<span class="comment single">// Equivalent without- and with-executor async statements with launch policy
</span>
<span class="keyword">auto</span> <span class="name">f</span> <span class="operator">=</span> <span class="name">std</span><span class="operator">::</span><span class="name">async</span><span class="punctuation">(</span> <span class="name">std</span><span class="operator">::</span><span class="name">launch</span><span class="operator">::</span><span class="name">deferred</span> <span class="punctuation">,</span> <span class="punctuation">[]{</span> <span class="name">std</span><span class="operator">::</span><span class="name">cout</span> <span class="operator">&lt;&lt;</span> <span class="literal string">&quot;anonymous way</span><span class="literal string escape">\n</span><span class="literal string">&quot;</span><span class="punctuation">}</span> <span class="punctuation">);</span>
<span class="keyword">auto</span> <span class="name">f</span> <span class="operator">=</span> <span class="name">std</span><span class="operator">::</span><span class="name">async</span><span class="punctuation">(</span> <span class="name">std</span><span class="operator">::</span><span class="name">async_execution_context</span><span class="punctuation">.</span><span class="name">executor</span><span class="punctuation">(</span> <span class="name">std</span><span class="operator">::</span><span class="name">launch</span><span class="operator">::</span><span class="name">deferred</span> <span class="punctuation">)</span> <span class="punctuation">,</span> <span class="punctuation">[]{</span> <span class="name">std</span><span class="operator">::</span><span class="name">cout</span> <span class="operator">&lt;&lt;</span> <span class="literal string">&quot;executor way</span><span class="literal string escape">\n</span><span class="literal string">&quot;</span><span class="punctuation">}</span> <span class="punctuation">);</span>
</pre>
<!--  -->
</div>
<div class="section" id="wording-for-standard-async-execution-context-and-executor">
<h2>Wording for Standard Async Execution Context and Executor</h2>
<pre class="code c++ literal-block">
<span class="keyword">namespace</span> <span class="name">std</span> <span class="punctuation">{</span>

<span class="keyword">struct</span> <span class="keyword type">async_execution_context_t</span> <span class="punctuation">{</span>
  <span class="comment single">// conforming to ExecutionContext concept
</span>
  <span class="comment single">// Execution resource
</span>  <span class="keyword">using</span> <span class="keyword type">execution_resource_t</span> <span class="operator">=</span> <span class="keyword type">thread_execution_resource_t</span> <span class="punctuation">;</span>

  <span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">ExecutorProperties</span> <span class="operator">&gt;</span>
    <span class="comment multiline">/* exposition only */</span> <span class="name">detail</span><span class="operator">::</span><span class="keyword type">executor_t</span><span class="operator">&lt;</span> <span class="keyword type">async_execution_context_t</span> <span class="punctuation">,</span> <span class="name">ExecutorProperties</span><span class="punctuation">...</span> <span class="operator">&gt;</span>
  <span class="name">executor</span><span class="punctuation">(</span> <span class="name">ExecutorProperties</span> <span class="punctuation">...</span> <span class="name">p</span> <span class="punctuation">);</span><span class="error">``</span>
<span class="punctuation">};</span>

<span class="keyword">class</span> <span class="name class">async_executor_t</span> <span class="punctuation">;</span> <span class="comment single">// implementation defined
</span>
<span class="keyword">extern</span> <span class="keyword type">async_execution_context_t</span> <span class="name">async_execution_context</span> <span class="punctuation">;</span>

<span class="keyword">template</span><span class="operator">&lt;</span> <span class="keyword">class</span> <span class="name class">Function</span> <span class="punctuation">,</span> <span class="keyword">class</span> <span class="error">... </span><span class="name class">Args</span> <span class="operator">&gt;</span>
<span class="name">future</span><span class="operator">&lt;</span><span class="name">std</span><span class="operator">::</span><span class="name">result_of</span><span class="operator">&lt;</span><span class="name">std</span><span class="operator">::</span><span class="keyword type">decay_t</span><span class="operator">&lt;</span><span class="name">Function</span><span class="operator">&gt;</span><span class="punctuation">(</span><span class="name">std</span><span class="operator">::</span><span class="keyword type">decay_t</span><span class="operator">&lt;</span><span class="name">Args</span><span class="operator">&gt;</span><span class="punctuation">...)</span><span class="operator">&gt;&gt;</span>
<span class="name">async</span><span class="punctuation">(</span> <span class="keyword type">async_executor_t</span> <span class="name">exec</span> <span class="punctuation">,</span> <span class="name">Function</span> <span class="operator">&amp;&amp;</span> <span class="name">f</span> <span class="punctuation">,</span> <span class="name">Args</span> <span class="operator">&amp;&amp;</span> <span class="punctuation">...</span> <span class="name">args</span> <span class="punctuation">);</span>

<span class="punctuation">}</span>
</pre>
<!--  -->
<p><tt class="docutils literal">extern async_execution_context_t async_execution_context;</tt></p>
<blockquote>
Global execution context object enabling the
equivalent invocation of callables
through the with-executor <tt class="docutils literal"><span class="pre">std::async</span></tt>
and without-executor <tt class="docutils literal"><span class="pre">std::async</span></tt>.
Guaranteed to be initialized during or before the first use.
[Note: It is likely that
<tt class="docutils literal">async_execution_context == program_thread_execution_context</tt>.
--end note]</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class ... ExecutorProperties &gt;</tt></div>
<div class="line-block">
<div class="line"><tt class="docutils literal">/* exposition only */ <span class="pre">detail::executor_t&lt;</span> async_execution_context_t , <span class="pre">ExecutorProperties...</span> &gt;</tt></div>
</div>
<div class="line"><tt class="docutils literal"><span class="pre">async_execution_context_t::executor(</span> ExecutorProperties ... p );</tt></div>
</div>
<blockquote>
Returns:
An <em>executor</em> with <tt class="docutils literal">*this</tt> <em>execution context</em> and
execution properties <tt class="docutils literal">p</tt>.
If <tt class="docutils literal">p</tt> is empty, is <tt class="docutils literal"><span class="pre">std::launch::async</span></tt>, or is <tt class="docutils literal"><span class="pre">std::launch::deferred</span></tt>
the <em>executor</em> type is <tt class="docutils literal">async_executor_t</tt>.</blockquote>
<div class="line-block">
<div class="line"><tt class="docutils literal">template&lt; class Function , class ... Args &gt;</tt></div>
<div class="line"><tt class="docutils literal"><span class="pre">future&lt;std::result_of&lt;std::decay_t&lt;Function&gt;(std::decay_t&lt;Args&gt;...)&gt;&gt;</span></tt></div>
<div class="line"><tt class="docutils literal">async( async_executor_t exec , Function &amp;&amp; f , Args &amp;&amp; ... args );</tt></div>
</div>
<blockquote>
Effects:
If <tt class="docutils literal">exec</tt> has a <tt class="docutils literal"><span class="pre">std::launch</span></tt> <em>policy</em>
then equivalent to invoking <tt class="docutils literal"><span class="pre">std::async(</span></tt> <em>policy</em> <tt class="docutils literal">, f , <span class="pre">args...</span> );</tt>
otherwise equivalent to invoking <tt class="docutils literal"><span class="pre">std::async(</span> f , <span class="pre">args...</span> );</tt>
Equivalency is symmetric with respect to the non-executor <tt class="docutils literal"><span class="pre">std::async</span></tt>
functions.</blockquote>
</div>
</div>
<div class="section" id="appendices">
<h1>Appendices</h1>
<div class="section" id="potential-additions-request-straw-poll-for-each">
<h2>Potential Additions: Request straw poll for each</h2>
<p id="potential-additions">Straw polls requested for each of the following potential additions.</p>
<blockquote>
<ul class="simple">
<li>Strongly-favor = I must have this in next revision of this paper.</li>
<li>Weakly-favor = I'd like to see this in a future paper, or perhaps the next revision.</li>
<li>Neutral = <em>whatever</em></li>
<li>Weakly-against = I don't want to see this in the next revision of this paper, but I am willing to look at it in a future paper.</li>
<li>Strongly-against = I never want to see this in any paper.</li>
</ul>
<ol class="arabic simple">
<li>Add to <cite>thread_execution_resource_t</cite> a hardware architecture trait;
e.g., the <strong>hwloc</strong> trait for <em>socket</em>, <em>numa</em>, and <em>core</em>.</li>
<li>A mechanism to bind the execution of a <tt class="docutils literal"><span class="pre">std::thread</span></tt> to
a specified <tt class="docutils literal">thread_execution_resource</tt>.
Note that by definition all <tt class="docutils literal"><span class="pre">std::thread</span></tt> are bound to
<tt class="docutils literal">program_thread_execution_resource</tt>.</li>
<li>A mechanism to accumulate and query exceptions thrown by
callables that were submitted by a one-way executor.</li>
<li>A mechanism to provide a callable that is invoked to consume
exceptions thrown by callables that were submitted by a one-way executor.</li>
<li>A mechanism for preventing further submissions.
Related to &quot;closed&quot; in Concurrent Queue paper P0260.</li>
<li>A mechanism for cancelling submitted callables that have not been invoked.
Similar intent as Networking TS <tt class="docutils literal"><span class="pre">system_executor::stop()</span></tt>.
Note that an execution resource and associated execution context
may not be able to cancel submitted work; e.g., submitted to a
hardware queue or to a remote dispatch-and-forget queue.</li>
<li>A mechanism for aborting callables that are executing.
<em>Included for completeness, the authors are strongly-against.</em></li>
<li>A preferred-locality (affinity) memory space allocator</li>
<li>Proposal to revise Networking TS execution context to align with
parallelism and concurrency execution context.</li>
<li>Current <cite>thread_execution_resource_t</cite> assumes static set of
processing units with static hierarchical partitioning topology.
A process' set of processing units and associated topology could be
dynamic such that an executing process could adapt to changes;
e.g., cores could dynamically go off-line and previously off-line
cores could come back on-line.
A dynamic set of processing units and dynamic hierarchical
partitioning topology would require a complete redesign to address
race conditions between querying and changing the execution resource.
<em>Authors need to see a performant runtime that handles such dynamicity
before considering such a change.</em></li>
</ol>
</blockquote>
<!-- Note: Boost "ASIO" library -->
</div>
</div>
</div>
</body>
</html>
