From Jason Turner

[thread.req]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpebofzy3c/{from.md → to.md} +115 -22
tmp/tmpebofzy3c/{from.md → to.md} RENAMED
@@ -1,15 +1,20 @@
1
  ## Requirements <a id="thread.req">[[thread.req]]</a>
2
 
3
  ### Template parameter names <a id="thread.req.paramname">[[thread.req.paramname]]</a>
4
 
5
  Throughout this Clause, the names of template parameters are used to
6
- express type requirements. If a template parameter is named `Predicate`,
7
- `operator()` applied to the template argument shall return a value that
8
- is convertible to `bool`. If a template parameter is named `Clock`, the
9
- corresponding template argument shall be a type `C` for which
10
- `is_clock_v<C>` is `true`; otherwise the program is ill-formed.
 
 
 
 
 
11
 
12
  ### Exceptions <a id="thread.req.exception">[[thread.req.exception]]</a>
13
 
14
  Some functions described in this Clause are specified to throw
15
  exceptions of type `system_error` [[syserr.syserr]]. Such exceptions are
@@ -17,11 +22,11 @@ thrown if any of the function’s error conditions is detected or a call
17
  to an operating system or other underlying API results in an error that
18
  prevents the library function from meeting its specifications. Failure
19
  to allocate storage is reported as described in 
20
  [[res.on.exception.handling]].
21
 
22
- [*Example 1*: Consider a function in this clause that is specified to
23
  throw exceptions of type `system_error` and specifies error conditions
24
  that include `operation_not_permitted` for a thread that does not have
25
  the privilege to perform the operation. Assume that, during the
26
  execution of this function, an `errno` of `EPERM` is reported by a POSIX
27
  API call used by the implementation. Since POSIX specifies an `errno` of
@@ -59,12 +64,13 @@ and memory resources induces a “quality of management” delay, expressed
59
  as duration Dₘ. The delay durations may vary from timeout to timeout,
60
  but in all cases shorter is better.
61
 
62
  The functions whose names end in `_for` take an argument that specifies
63
  a duration. These functions produce relative timeouts. Implementations
64
- should use a steady clock to measure time for these functions.[^1] Given
65
- a duration argument Dₜ, the real-time duration of the timeout is
 
66
  Dₜ + Dᵢ + Dₘ.
67
 
68
  The functions whose names end in `_until` take an argument that
69
  specifies a time point. These functions produce absolute timeouts.
70
  Implementations should use the clock specified in the time point to
@@ -72,15 +78,15 @@ measure time for these functions. Given a clock time point argument Cₜ,
72
  the clock time point of the return from timeout should be Cₜ + Dᵢ + Dₘ
73
  when the clock is not adjusted during the timeout. If the clock is
74
  adjusted to the time Cₐ during the timeout, the behavior should be as
75
  follows:
76
 
77
- - if Cₐ > Cₜ, the waiting function should wake as soon as possible,
78
  i.e., Cₐ + Dᵢ + Dₘ, since the timeout is already satisfied. This
79
  specification may result in the total duration of the wait decreasing
80
  when measured against a steady clock.
81
- - if Cₐ ≤ Cₜ, the waiting function should not time out until
82
  `Clock::now()` returns a time Cₙ ≥ Cₜ, i.e., waking at Cₜ + Dᵢ + Dₘ.
83
  \[*Note 1*: When the clock is adjusted backwards, this specification
84
  can result in the total duration of the wait increasing when measured
85
  against a steady clock. When the clock is adjusted forwards, this
86
  specification can result in the total duration of the wait decreasing
@@ -89,15 +95,15 @@ follows:
89
  An implementation returns from such a timeout at any point from the time
90
  specified above to the time it would return from a steady-clock relative
91
  timeout on the difference between Cₜ and the time point of the call to
92
  the `_until` function.
93
 
94
- [*Note 2*: Implementations should decrease the duration of the wait
95
- when the clock is adjusted forwards. — *end note*]
96
 
97
- [*Note 3*: If the clock is not synchronized with a steady clock, e.g.,
98
- a CPU time clock, these timeouts might not provide useful
99
  functionality. — *end note*]
100
 
101
  The resolution of timing provided by an implementation depends on both
102
  operating system and hardware. The finest resolution provided by an
103
  implementation is called the *native resolution*.
@@ -108,11 +114,11 @@ the *Cpp17TrivialClock* requirements [[time.clock.req]].
108
  A function that takes an argument which specifies a timeout will throw
109
  if, during its execution, a clock, time point, or time duration throws
110
  an exception. Such exceptions are referred to as *timeout-related
111
  exceptions*.
112
 
113
- [*Note 4*: Instantiations of clock, time point and duration types
114
  supplied by the implementation as specified in  [[time.clock]] do not
115
  throw exceptions. — *end note*]
116
 
117
  ### Requirements for *Cpp17Lockable* types <a id="thread.req.lockable">[[thread.req.lockable]]</a>
118
 
@@ -135,17 +141,31 @@ The standard library templates `unique_lock` [[thread.lock.unique]],
135
  `shared_lock` [[thread.lock.shared]], `scoped_lock`
136
  [[thread.lock.scoped]], `lock_guard` [[thread.lock.guard]], `lock`,
137
  `try_lock` [[thread.lock.algorithm]], and `condition_variable_any`
138
  [[thread.condition.condvarany]] all operate on user-supplied lockable
139
  objects. The *Cpp17BasicLockable* requirements, the *Cpp17Lockable*
140
- requirements, and the *Cpp17TimedLockable* requirements list the
141
- requirements imposed by these library types in order to acquire or
142
- release ownership of a `lock` by a given execution agent.
 
 
143
 
144
  [*Note 3*: The nature of any lock ownership and any synchronization it
145
  entails are not part of these requirements. — *end note*]
146
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  #### *Cpp17BasicLockable* requirements <a id="thread.req.lockable.basic">[[thread.req.lockable.basic]]</a>
148
 
149
  A type `L` meets the *Cpp17BasicLockable* requirements if the following
150
  expressions are well-formed and have the specified semantics (`m`
151
  denotes a value of type `L`).
@@ -160,13 +180,15 @@ acquired for the current execution agent.
160
 
161
  ``` cpp
162
  m.unlock()
163
  ```
164
 
165
- *Preconditions:* The current execution agent holds a lock on `m`.
 
166
 
167
- *Effects:* Releases a lock on `m` held by the current execution agent.
 
168
 
169
  *Throws:* Nothing.
170
 
171
  #### *Cpp17Lockable* requirements <a id="thread.req.lockable.req">[[thread.req.lockable.req]]</a>
172
 
@@ -183,11 +205,11 @@ m.try_lock()
183
  without blocking. If an exception is thrown then a lock shall not have
184
  been acquired for the current execution agent.
185
 
186
  *Return type:* `bool`.
187
 
188
- *Returns:* `true` if the lock was acquired, `false` otherwise.
189
 
190
  #### *Cpp17TimedLockable* requirements <a id="thread.req.lockable.timed">[[thread.req.lockable.timed]]</a>
191
 
192
  A type `L` meets the *Cpp17TimedLockable* requirements if it meets the
193
  *Cpp17Lockable* requirements and the following expressions are
@@ -207,11 +229,11 @@ within the relative timeout [[thread.req.timing]] specified by
207
  execution agent. If an exception is thrown then a lock has not been
208
  acquired for the current execution agent.
209
 
210
  *Return type:* `bool`.
211
 
212
- *Returns:* `true` if the lock was acquired, `false` otherwise.
213
 
214
  ``` cpp
215
  m.try_lock_until(abs_time)
216
  ```
217
 
@@ -222,7 +244,78 @@ before the absolute timeout [[thread.req.timing]] specified by
222
  execution agent. If an exception is thrown then a lock has not been
223
  acquired for the current execution agent.
224
 
225
  *Return type:* `bool`.
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  *Returns:* `true` if the lock was acquired, `false` otherwise.
228
 
 
1
  ## Requirements <a id="thread.req">[[thread.req]]</a>
2
 
3
  ### Template parameter names <a id="thread.req.paramname">[[thread.req.paramname]]</a>
4
 
5
  Throughout this Clause, the names of template parameters are used to
6
+ express type requirements. `Predicate` is a function object type
7
+ [[function.objects]]. Let `pred` denote an lvalue of type `Predicate`.
8
+ Then the expression `pred()` shall be well-formed and the type
9
+ `decltype(pred())` shall model `boolean-testable`
10
+ [[concept.booleantestable]]. The return value of `pred()`, converted to
11
+ `bool`, yields `true` if the corresponding test condition is satisfied,
12
+ and `false` otherwise. If a template parameter is named `Clock`, the
13
+ corresponding template argument shall be a type `C` that meets the
14
+ *Cpp17Clock* requirements [[time.clock.req]]; the program is ill-formed
15
+ if `is_clock_v<C>` is `false`.
16
 
17
  ### Exceptions <a id="thread.req.exception">[[thread.req.exception]]</a>
18
 
19
  Some functions described in this Clause are specified to throw
20
  exceptions of type `system_error` [[syserr.syserr]]. Such exceptions are
 
22
  to an operating system or other underlying API results in an error that
23
  prevents the library function from meeting its specifications. Failure
24
  to allocate storage is reported as described in 
25
  [[res.on.exception.handling]].
26
 
27
+ [*Example 1*: Consider a function in this Clause that is specified to
28
  throw exceptions of type `system_error` and specifies error conditions
29
  that include `operation_not_permitted` for a thread that does not have
30
  the privilege to perform the operation. Assume that, during the
31
  execution of this function, an `errno` of `EPERM` is reported by a POSIX
32
  API call used by the implementation. Since POSIX specifies an `errno` of
 
64
  as duration Dₘ. The delay durations may vary from timeout to timeout,
65
  but in all cases shorter is better.
66
 
67
  The functions whose names end in `_for` take an argument that specifies
68
  a duration. These functions produce relative timeouts. Implementations
69
+ should use a steady clock to measure time for these functions.[^1]
70
+
71
+ Given a duration argument Dₜ, the real-time duration of the timeout is
72
  Dₜ + Dᵢ + Dₘ.
73
 
74
  The functions whose names end in `_until` take an argument that
75
  specifies a time point. These functions produce absolute timeouts.
76
  Implementations should use the clock specified in the time point to
 
78
  the clock time point of the return from timeout should be Cₜ + Dᵢ + Dₘ
79
  when the clock is not adjusted during the timeout. If the clock is
80
  adjusted to the time Cₐ during the timeout, the behavior should be as
81
  follows:
82
 
83
+ - If Cₐ > Cₜ, the waiting function should wake as soon as possible,
84
  i.e., Cₐ + Dᵢ + Dₘ, since the timeout is already satisfied. This
85
  specification may result in the total duration of the wait decreasing
86
  when measured against a steady clock.
87
+ - If Cₐ ≤ Cₜ, the waiting function should not time out until
88
  `Clock::now()` returns a time Cₙ ≥ Cₜ, i.e., waking at Cₜ + Dᵢ + Dₘ.
89
  \[*Note 1*: When the clock is adjusted backwards, this specification
90
  can result in the total duration of the wait increasing when measured
91
  against a steady clock. When the clock is adjusted forwards, this
92
  specification can result in the total duration of the wait decreasing
 
95
  An implementation returns from such a timeout at any point from the time
96
  specified above to the time it would return from a steady-clock relative
97
  timeout on the difference between Cₜ and the time point of the call to
98
  the `_until` function.
99
 
100
+ *Recommended practice:* Implementations should decrease the duration of
101
+ the wait when the clock is adjusted forwards.
102
 
103
+ [*Note 2*: If the clock is not synchronized with a steady clock, e.g.,
104
+ a CPU time clock, these timeouts can fail to provide useful
105
  functionality. — *end note*]
106
 
107
  The resolution of timing provided by an implementation depends on both
108
  operating system and hardware. The finest resolution provided by an
109
  implementation is called the *native resolution*.
 
114
  A function that takes an argument which specifies a timeout will throw
115
  if, during its execution, a clock, time point, or time duration throws
116
  an exception. Such exceptions are referred to as *timeout-related
117
  exceptions*.
118
 
119
+ [*Note 3*: Instantiations of clock, time point and duration types
120
  supplied by the implementation as specified in  [[time.clock]] do not
121
  throw exceptions. — *end note*]
122
 
123
  ### Requirements for *Cpp17Lockable* types <a id="thread.req.lockable">[[thread.req.lockable]]</a>
124
 
 
141
  `shared_lock` [[thread.lock.shared]], `scoped_lock`
142
  [[thread.lock.scoped]], `lock_guard` [[thread.lock.guard]], `lock`,
143
  `try_lock` [[thread.lock.algorithm]], and `condition_variable_any`
144
  [[thread.condition.condvarany]] all operate on user-supplied lockable
145
  objects. The *Cpp17BasicLockable* requirements, the *Cpp17Lockable*
146
+ requirements, the *Cpp17TimedLockable* requirements, the
147
+ *Cpp17SharedLockable* requirements, and the *Cpp17SharedTimedLockable*
148
+ requirements list the requirements imposed by these library types in
149
+ order to acquire or release ownership of a `lock` by a given execution
150
+ agent.
151
 
152
  [*Note 3*: The nature of any lock ownership and any synchronization it
153
  entails are not part of these requirements. — *end note*]
154
 
155
+ A lock on an object `m` is said to be
156
+
157
+ - a *non-shared lock* if it is acquired by a call to `lock`, `try_lock`,
158
+ `try_lock_for`, or `try_lock_until` on `m`, or
159
+ - a *shared lock* if it is acquired by a call to `lock_shared`,
160
+ `try_lock_shared`, `try_lock_shared_for`, or `try_lock_shared_until`
161
+ on `m`.
162
+
163
+ [*Note 4*: Only the method of lock acquisition is considered; the
164
+ nature of any lock ownership is not part of these
165
+ definitions. — *end note*]
166
+
167
  #### *Cpp17BasicLockable* requirements <a id="thread.req.lockable.basic">[[thread.req.lockable.basic]]</a>
168
 
169
  A type `L` meets the *Cpp17BasicLockable* requirements if the following
170
  expressions are well-formed and have the specified semantics (`m`
171
  denotes a value of type `L`).
 
180
 
181
  ``` cpp
182
  m.unlock()
183
  ```
184
 
185
+ *Preconditions:* The current execution agent holds a non-shared lock on
186
+ `m`.
187
 
188
+ *Effects:* Releases a non-shared lock on `m` held by the current
189
+ execution agent.
190
 
191
  *Throws:* Nothing.
192
 
193
  #### *Cpp17Lockable* requirements <a id="thread.req.lockable.req">[[thread.req.lockable.req]]</a>
194
 
 
205
  without blocking. If an exception is thrown then a lock shall not have
206
  been acquired for the current execution agent.
207
 
208
  *Return type:* `bool`.
209
 
210
+ *Returns:* `true` if the lock was acquired, otherwise `false`.
211
 
212
  #### *Cpp17TimedLockable* requirements <a id="thread.req.lockable.timed">[[thread.req.lockable.timed]]</a>
213
 
214
  A type `L` meets the *Cpp17TimedLockable* requirements if it meets the
215
  *Cpp17Lockable* requirements and the following expressions are
 
229
  execution agent. If an exception is thrown then a lock has not been
230
  acquired for the current execution agent.
231
 
232
  *Return type:* `bool`.
233
 
234
+ *Returns:* `true` if the lock was acquired, otherwise `false`.
235
 
236
  ``` cpp
237
  m.try_lock_until(abs_time)
238
  ```
239
 
 
244
  execution agent. If an exception is thrown then a lock has not been
245
  acquired for the current execution agent.
246
 
247
  *Return type:* `bool`.
248
 
249
+ *Returns:* `true` if the lock was acquired, otherwise `false`.
250
+
251
+ #### *Cpp17SharedLockable* requirements <a id="thread.req.lockable.shared">[[thread.req.lockable.shared]]</a>
252
+
253
+ A type `L` meets the *Cpp17SharedLockable* requirements if the following
254
+ expressions are well-formed, have the specified semantics, and the
255
+ expression `m.try_lock_shared()` has type `bool` (`m` denotes a value of
256
+ type `L`):
257
+
258
+ ``` cpp
259
+ m.lock_shared()
260
+ ```
261
+
262
+ *Effects:* Blocks until a lock can be acquired for the current execution
263
+ agent. If an exception is thrown then a lock shall not have been
264
+ acquired for the current execution agent.
265
+
266
+ ``` cpp
267
+ m.try_lock_shared()
268
+ ```
269
+
270
+ *Effects:* Attempts to acquire a lock for the current execution agent
271
+ without blocking. If an exception is thrown then a lock shall not have
272
+ been acquired for the current execution agent.
273
+
274
+ *Returns:* `true` if the lock was acquired, `false` otherwise.
275
+
276
+ ``` cpp
277
+ m.unlock_shared()
278
+ ```
279
+
280
+ *Preconditions:* The current execution agent holds a shared lock on `m`.
281
+
282
+ *Effects:* Releases a shared lock on `m` held by the current execution
283
+ agent.
284
+
285
+ *Throws:* Nothing.
286
+
287
+ #### *Cpp17SharedTimedLockable* requirements <a id="thread.req.lockable.shared.timed">[[thread.req.lockable.shared.timed]]</a>
288
+
289
+ A type `L` meets the *Cpp17SharedTimedLockable* requirements if it meets
290
+ the *Cpp17SharedLockable* requirements, and the following expressions
291
+ are well-formed, have type `bool`, and have the specified semantics (`m`
292
+ denotes a value of type `L`, `rel_time` denotes a value of a
293
+ specialization of `chrono::duration`, and `abs_time` denotes a value of
294
+ a specialization of `chrono::time_point`).
295
+
296
+ ``` cpp
297
+ m.try_lock_shared_for(rel_time)
298
+ ```
299
+
300
+ *Effects:* Attempts to acquire a lock for the current execution agent
301
+ within the relative timeout [[thread.req.timing]] specified by
302
+ `rel_time`. The function will not return within the timeout specified by
303
+ `rel_time` unless it has obtained a lock on `m` for the current
304
+ execution agent. If an exception is thrown then a lock has not been
305
+ acquired for the current execution agent.
306
+
307
+ *Returns:* `true` if the lock was acquired, `false` otherwise.
308
+
309
+ ``` cpp
310
+ m.try_lock_shared_until(abs_time)
311
+ ```
312
+
313
+ *Effects:* Attempts to acquire a lock for the current execution agent
314
+ before the absolute timeout [[thread.req.timing]] specified by
315
+ `abs_time`. The function will not return before the timeout specified by
316
+ `abs_time` unless it has obtained a lock on `m` for the current
317
+ execution agent. If an exception is thrown then a lock has not been
318
+ acquired for the current execution agent.
319
+
320
  *Returns:* `true` if the lock was acquired, `false` otherwise.
321