From Jason Turner

[exec.ctx]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwelg8_yw/{from.md → to.md} +219 -0
tmp/tmpwelg8_yw/{from.md → to.md} RENAMED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Execution contexts <a id="exec.ctx">[[exec.ctx]]</a>
2
+
3
+ ### `execution::run_loop` <a id="exec.run.loop">[[exec.run.loop]]</a>
4
+
5
+ #### General <a id="exec.run.loop.general">[[exec.run.loop.general]]</a>
6
+
7
+ A `run_loop` is an execution resource on which work can be scheduled. It
8
+ maintains a thread-safe first-in-first-out queue of work. Its `run`
9
+ member function removes elements from the queue and executes them in a
10
+ loop on the thread of execution that calls `run`.
11
+
12
+ A `run_loop` instance has an associated *count* that corresponds to the
13
+ number of work items that are in its queue. Additionally, a `run_loop`
14
+ instance has an associated state that can be one of *starting*,
15
+ *running*, *finishing*, or *finished*.
16
+
17
+ Concurrent invocations of the member functions of `run_loop` other than
18
+ `run` and its destructor do not introduce data races. The member
19
+ functions *`pop-front`*, *`push-back`*, and `finish` execute atomically.
20
+
21
+ *Recommended practice:* Implementations should use an intrusive queue of
22
+ operation states to hold the work units to make scheduling
23
+ allocation-free.
24
+
25
+ ``` cpp
26
+ namespace std::execution {
27
+ class run_loop {
28
+ // [exec.run.loop.types], associated types
29
+ class run-loop-scheduler; // exposition only
30
+ class run-loop-sender; // exposition only
31
+ struct run-loop-opstate-base { // exposition only
32
+ virtual void execute() = 0; // exposition only
33
+ run_loop* loop; // exposition only
34
+ run-loop-opstate-base* next; // exposition only
35
+ };
36
+ template<class Rcvr>
37
+ using run-loop-opstate = unspecified; // exposition only
38
+
39
+ // [exec.run.loop.members], member functions
40
+ run-loop-opstate-base* pop-front(); // exposition only
41
+ void push-back(run-loop-opstate-base*); // exposition only
42
+
43
+ public:
44
+ // [exec.run.loop.ctor], constructor and destructor
45
+ run_loop() noexcept;
46
+ run_loop(run_loop&&) = delete;
47
+ ~run_loop();
48
+
49
+ // [exec.run.loop.members], member functions
50
+ run-loop-scheduler get_scheduler();
51
+ void run();
52
+ void finish();
53
+ };
54
+ }
55
+ ```
56
+
57
+ #### Associated types <a id="exec.run.loop.types">[[exec.run.loop.types]]</a>
58
+
59
+ ``` cpp
60
+ class run-loop-scheduler;
61
+ ```
62
+
63
+ *`run-loop-scheduler`* is an unspecified type that models `scheduler`.
64
+
65
+ Instances of *`run-loop-scheduler`* remain valid until the end of the
66
+ lifetime of the `run_loop` instance from which they were obtained.
67
+
68
+ Two instances of *`run-loop-scheduler`* compare equal if and only if
69
+ they were obtained from the same `run_loop` instance.
70
+
71
+ Let *`sch`* be an expression of type *`run-loop-scheduler`*. The
72
+ expression `schedule(sch)` has type *`run-loop- sender`* and is not
73
+ potentially-throwing if *`sch`* is not potentially-throwing.
74
+
75
+ ``` cpp
76
+ class run-loop-sender;
77
+ ```
78
+
79
+ *`run-loop-sender`* is an exposition-only type that satisfies `sender`.
80
+ `completion_signatures_of_t<run-{loop-sender}>` is
81
+
82
+ ``` cpp
83
+ completion_signatures<set_value_t(), set_error_t(exception_ptr), set_stopped_t()>
84
+ ```
85
+
86
+ An instance of *`run-loop-sender`* remains valid until the end of the
87
+ lifetime of its associated `run_loop` instance.
88
+
89
+ Let *`sndr`* be an expression of type *`run-loop-sender`*, let *`rcvr`*
90
+ be an expression such that `receiver_of<decltype((rcvr)), CS>` is `true`
91
+ where `CS` is the `completion_signatures` specialization above. Let `C`
92
+ be either `set_value_t` or `set_stopped_t`. Then:
93
+
94
+ - The expression `connect(sndr, rcvr)` has type
95
+ `run-loop-opstate<decay_t<decltype((rcvr))>>` and is
96
+ potentially-throwing if and only if `(void(sndr), auto(rcvr))` is
97
+ potentially-throwing.
98
+ - The expression `get_completion_scheduler<C>(get_env(sndr))` is
99
+ potentially-throwing if and only if *`sndr`* is potentially-throwing,
100
+ has type *`run-loop-scheduler`*, and compares equal to the
101
+ *`run-loop- scheduler`* instance from which *`sndr`* was obtained.
102
+
103
+ ``` cpp
104
+ template<class Rcvr>
105
+ struct run-loop-opstate;
106
+ ```
107
+
108
+ `\exposid{run-loop-opstate}<Rcvr>`
109
+
110
+ inherits privately and unambiguously from *`run-loop-opstate-base`*.
111
+
112
+ Let o be a non-const lvalue of type `run-loop-opstate<Rcvr>`, and let
113
+ `REC(o)` be a non-const lvalue reference to an instance of type `Rcvr`
114
+ that was initialized with the expression *`rcvr`* passed to the
115
+ invocation of connect that returned o. Then:
116
+
117
+ - The object to which `REC(o)` refers remains valid for the lifetime of
118
+ the object to which o refers.
119
+ - The type `run-loop-opstate<Rcvr>` overrides
120
+ `run-loop-opstate-base::execute()` such that `o.execute()` is
121
+ equivalent to:
122
+ ``` cpp
123
+ if (get_stop_token(REC(o)).stop_requested()) {
124
+ set_stopped(std::move(REC(o)));
125
+ } else {
126
+ set_value(std::move(REC(o)));
127
+ }
128
+ ```
129
+ - The expression `start(o)` is equivalent to:
130
+ ``` cpp
131
+ try {
132
+ o.loop->push-back(addressof(o));
133
+ } catch(...) {
134
+ set_error(std::move(REC(o)), current_exception());
135
+ }
136
+ ```
137
+
138
+ #### Constructor and destructor <a id="exec.run.loop.ctor">[[exec.run.loop.ctor]]</a>
139
+
140
+ ``` cpp
141
+ run_loop() noexcept;
142
+ ```
143
+
144
+ *Ensures:* The `run_loop` instance’s count is 0 and its state is
145
+ starting.
146
+
147
+ ``` cpp
148
+ ~run_loop();
149
+ ```
150
+
151
+ *Effects:* If the `run_loop` instance’s count is not 0 or if its state
152
+ is running, invokes `terminate` [[except.terminate]]. Otherwise, has no
153
+ effects.
154
+
155
+ #### Member functions <a id="exec.run.loop.members">[[exec.run.loop.members]]</a>
156
+
157
+ ``` cpp
158
+ run-loop-opstate-base* pop-front();
159
+ ```
160
+
161
+ *Effects:* Blocks [[defns.block]] until one of the following conditions
162
+ is `true`:
163
+
164
+ - The `run_loop` instance’s count is 0 and its state is finishing, in
165
+ which case *pop-front* sets the state to finished and returns
166
+ `nullptr`; or
167
+ - the `run_loop` instance’s count is greater than 0, in which case an
168
+ item is removed from the front of the queue, the count is decremented
169
+ by `1`, and the removed item is returned.
170
+
171
+ ``` cpp
172
+ void push-back(run-loop-opstate-base* item);
173
+ ```
174
+
175
+ *Effects:* Adds `item` to the back of the queue and increments the
176
+ `run_loop` instance’s count by 1.
177
+
178
+ *Synchronization:* This operation synchronizes with the *pop-front*
179
+ operation that obtains `item`.
180
+
181
+ ``` cpp
182
+ run-loop-scheduler get_scheduler();
183
+ ```
184
+
185
+ *Returns:* An instance of *run-loop-scheduler* that can be used to
186
+ schedule work onto this `run_loop` instance.
187
+
188
+ ``` cpp
189
+ void run();
190
+ ```
191
+
192
+ *Preconditions:* The `run_loop` instance’s state is either starting or
193
+ finishing.
194
+
195
+ *Effects:* If the `run_loop` instance’s state is starting, sets the
196
+ state to running, otherwise leaves the state unchanged. Then, equivalent
197
+ to:
198
+
199
+ ``` cpp
200
+ while (auto* op = pop-front()) {
201
+ op->execute();
202
+ }
203
+ ```
204
+
205
+ *Remarks:* When the `run_loop` instance’s state changes, it does so
206
+ without introducing data races.
207
+
208
+ ``` cpp
209
+ void finish();
210
+ ```
211
+
212
+ *Preconditions:* The `run_loop` instance’s state is either starting or
213
+ running.
214
+
215
+ *Effects:* Changes the `run_loop` instance’s state to finishing.
216
+
217
+ *Synchronization:* `finish` synchronizes with the *pop-front* operation
218
+ that returns `nullptr`.
219
+