- 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.
|
| 7 |
-
`
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 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]
|
| 65 |
-
|
|
|
|
| 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 |
-
-
|
| 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 |
-
-
|
| 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 |
-
|
| 95 |
-
when the clock is adjusted forwards.
|
| 96 |
|
| 97 |
-
[*Note
|
| 98 |
-
a CPU time clock, these timeouts
|
| 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
|
| 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,
|
| 141 |
-
requirements
|
| 142 |
-
|
|
|
|
|
|
|
| 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
|
|
|
|
| 166 |
|
| 167 |
-
*Effects:* Releases a lock on `m` held by the current
|
|
|
|
| 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`
|
| 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`
|
| 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 |
|