tmp/tmp7a0gz189/{from.md → to.md}
RENAMED
|
@@ -3,35 +3,37 @@
|
|
| 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`.
|
|
|
|
|
|
|
| 9 |
|
| 10 |
### Exceptions <a id="thread.req.exception">[[thread.req.exception]]</a>
|
| 11 |
|
| 12 |
Some functions described in this Clause are specified to throw
|
| 13 |
-
exceptions of type `system_error`
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
|
| 20 |
[*Example 1*: Consider a function in this clause that is specified to
|
| 21 |
throw exceptions of type `system_error` and specifies error conditions
|
| 22 |
that include `operation_not_permitted` for a thread that does not have
|
| 23 |
the privilege to perform the operation. Assume that, during the
|
| 24 |
execution of this function, an `errno` of `EPERM` is reported by a POSIX
|
| 25 |
API call used by the implementation. Since POSIX specifies an `errno` of
|
| 26 |
`EPERM` when “the caller does not have the privilege to perform the
|
| 27 |
operation”, the implementation maps `EPERM` to an `error_condition` of
|
| 28 |
-
`operation_not_permitted`
|
| 29 |
`system_error` is thrown. — *end example*]
|
| 30 |
|
| 31 |
The `error_code` reported by such an exception’s `code()` member
|
| 32 |
-
function
|
| 33 |
function’s error condition element.
|
| 34 |
|
| 35 |
### Native handles <a id="thread.req.native">[[thread.req.native]]</a>
|
| 36 |
|
| 37 |
Several classes described in this Clause have members
|
|
@@ -55,98 +57,98 @@ induces a “quality of implementation” delay, expressed as duration Dᵢ.
|
|
| 55 |
Ideally, this delay would be zero. Further, any contention for processor
|
| 56 |
and memory resources induces a “quality of management” delay, expressed
|
| 57 |
as duration Dₘ. The delay durations may vary from timeout to timeout,
|
| 58 |
but in all cases shorter is better.
|
| 59 |
|
| 60 |
-
The
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
|
| 66 |
-
The
|
| 67 |
specifies a time point. These functions produce absolute timeouts.
|
| 68 |
Implementations should use the clock specified in the time point to
|
| 69 |
measure time for these functions. Given a clock time point argument Cₜ,
|
| 70 |
the clock time point of the return from timeout should be Cₜ + Dᵢ + Dₘ
|
| 71 |
when the clock is not adjusted during the timeout. If the clock is
|
| 72 |
adjusted to the time Cₐ during the timeout, the behavior should be as
|
| 73 |
follows:
|
| 74 |
|
| 75 |
-
- if Cₐ > Cₜ, the waiting function should wake as soon as possible,
|
| 76 |
-
Cₐ + Dᵢ + Dₘ, since the timeout is already satisfied.
|
| 77 |
specification may result in the total duration of the wait decreasing
|
| 78 |
-
when measured against a steady clock.
|
| 79 |
-
- if Cₐ
|
| 80 |
-
`Clock::now()` returns a time Cₙ
|
| 81 |
-
\[*Note
|
| 82 |
-
|
| 83 |
against a steady clock. When the clock is adjusted forwards, this
|
| 84 |
-
specification
|
| 85 |
when measured against a steady clock. — *end note*]
|
| 86 |
|
| 87 |
-
An implementation
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
|
| 92 |
-
[*Note
|
| 93 |
when the clock is adjusted forwards. — *end note*]
|
| 94 |
|
| 95 |
-
[*Note
|
| 96 |
a CPU time clock, these timeouts might not provide useful
|
| 97 |
functionality. — *end note*]
|
| 98 |
|
| 99 |
The resolution of timing provided by an implementation depends on both
|
| 100 |
operating system and hardware. The finest resolution provided by an
|
| 101 |
implementation is called the *native resolution*.
|
| 102 |
|
| 103 |
-
Implementation-provided clocks that are used for these functions
|
| 104 |
-
|
| 105 |
|
| 106 |
A function that takes an argument which specifies a timeout will throw
|
| 107 |
if, during its execution, a clock, time point, or time duration throws
|
| 108 |
an exception. Such exceptions are referred to as *timeout-related
|
| 109 |
exceptions*.
|
| 110 |
|
| 111 |
-
[*Note
|
| 112 |
supplied by the implementation as specified in [[time.clock]] do not
|
| 113 |
throw exceptions. — *end note*]
|
| 114 |
|
| 115 |
-
### Requirements for
|
| 116 |
|
| 117 |
#### In general <a id="thread.req.lockable.general">[[thread.req.lockable.general]]</a>
|
| 118 |
|
| 119 |
An *execution agent* is an entity such as a thread that may perform work
|
| 120 |
in parallel with other execution agents.
|
| 121 |
|
| 122 |
-
[*Note 1*: Implementations or users
|
| 123 |
such as processes or thread-pool tasks. — *end note*]
|
| 124 |
|
| 125 |
-
The calling agent is determined by context, e.g. the calling thread
|
| 126 |
-
contains the call, and so on.
|
| 127 |
|
| 128 |
[*Note 2*: Some lockable objects are “agent oblivious” in that they
|
| 129 |
work for any execution agent model because they do not determine or
|
| 130 |
store the agent’s ID (e.g., an ordinary spin lock). — *end note*]
|
| 131 |
|
| 132 |
-
The standard library templates `unique_lock`
|
| 133 |
-
`shared_lock`
|
| 134 |
-
[[thread.lock.scoped]]
|
| 135 |
-
`try_lock`
|
| 136 |
-
[[thread.condition.condvarany]]
|
| 137 |
-
objects. The
|
| 138 |
-
and the
|
| 139 |
-
these library types in order to acquire or
|
| 140 |
-
by a given execution agent.
|
| 141 |
|
| 142 |
[*Note 3*: The nature of any lock ownership and any synchronization it
|
| 143 |
-
|
| 144 |
|
| 145 |
-
####
|
| 146 |
|
| 147 |
-
A type `L` meets the
|
| 148 |
expressions are well-formed and have the specified semantics (`m`
|
| 149 |
denotes a value of type `L`).
|
| 150 |
|
| 151 |
``` cpp
|
| 152 |
m.lock()
|
|
@@ -158,20 +160,20 @@ acquired for the current execution agent.
|
|
| 158 |
|
| 159 |
``` cpp
|
| 160 |
m.unlock()
|
| 161 |
```
|
| 162 |
|
| 163 |
-
*
|
| 164 |
|
| 165 |
*Effects:* Releases a lock on `m` held by the current execution agent.
|
| 166 |
|
| 167 |
*Throws:* Nothing.
|
| 168 |
|
| 169 |
-
####
|
| 170 |
|
| 171 |
-
A type `L` meets the
|
| 172 |
-
|
| 173 |
well-formed and have the specified semantics (`m` denotes a value of
|
| 174 |
type `L`).
|
| 175 |
|
| 176 |
``` cpp
|
| 177 |
m.try_lock()
|
|
@@ -183,55 +185,44 @@ been acquired for the current execution agent.
|
|
| 183 |
|
| 184 |
*Return type:* `bool`.
|
| 185 |
|
| 186 |
*Returns:* `true` if the lock was acquired, `false` otherwise.
|
| 187 |
|
| 188 |
-
####
|
| 189 |
|
| 190 |
-
A type `L` meets the
|
| 191 |
-
|
| 192 |
-
and have the specified semantics (`m` denotes a value of
|
| 193 |
-
`rel_time` denotes a value of an instantiation of `duration`
|
| 194 |
-
[[time.duration]]
|
| 195 |
-
|
| 196 |
|
| 197 |
``` cpp
|
| 198 |
m.try_lock_for(rel_time)
|
| 199 |
```
|
| 200 |
|
| 201 |
*Effects:* Attempts to acquire a lock for the current execution agent
|
| 202 |
-
within the relative timeout
|
| 203 |
-
`rel_time`. The function
|
| 204 |
-
|
| 205 |
-
execution agent. If an exception is thrown then a lock
|
| 206 |
-
|
| 207 |
|
| 208 |
*Return type:* `bool`.
|
| 209 |
|
| 210 |
*Returns:* `true` if the lock was acquired, `false` otherwise.
|
| 211 |
|
| 212 |
``` cpp
|
| 213 |
m.try_lock_until(abs_time)
|
| 214 |
```
|
| 215 |
|
| 216 |
*Effects:* Attempts to acquire a lock for the current execution agent
|
| 217 |
-
before the absolute timeout
|
| 218 |
-
`abs_time`. The function
|
| 219 |
-
|
| 220 |
-
execution agent. If an exception is thrown then a lock
|
| 221 |
-
|
| 222 |
|
| 223 |
*Return type:* `bool`.
|
| 224 |
|
| 225 |
*Returns:* `true` if the lock was acquired, `false` otherwise.
|
| 226 |
|
| 227 |
-
### `decay_copy` <a id="thread.decaycopy">[[thread.decaycopy]]</a>
|
| 228 |
-
|
| 229 |
-
In several places in this Clause the operation `DECAY_COPY(x)` is used.
|
| 230 |
-
All such uses mean call the function `decay_copy(x)` and use the result,
|
| 231 |
-
where `decay_copy` is defined as follows:
|
| 232 |
-
|
| 233 |
-
``` cpp
|
| 234 |
-
template <class T> decay_t<T> decay_copy(T&& v)
|
| 235 |
-
{ return std::forward<T>(v); }
|
| 236 |
-
```
|
| 237 |
-
|
|
|
|
| 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
|
| 16 |
+
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
|
| 28 |
`EPERM` when “the caller does not have the privilege to perform the
|
| 29 |
operation”, the implementation maps `EPERM` to an `error_condition` of
|
| 30 |
+
`operation_not_permitted` [[syserr]] and an exception of type
|
| 31 |
`system_error` is thrown. — *end example*]
|
| 32 |
|
| 33 |
The `error_code` reported by such an exception’s `code()` member
|
| 34 |
+
function compares equal to one of the conditions specified in the
|
| 35 |
function’s error condition element.
|
| 36 |
|
| 37 |
### Native handles <a id="thread.req.native">[[thread.req.native]]</a>
|
| 38 |
|
| 39 |
Several classes described in this Clause have members
|
|
|
|
| 57 |
Ideally, this delay would be zero. Further, any contention for processor
|
| 58 |
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
|
| 71 |
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
|
| 87 |
when measured against a steady clock. — *end note*]
|
| 88 |
|
| 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*.
|
| 104 |
|
| 105 |
+
Implementation-provided clocks that are used for these functions meet
|
| 106 |
+
the *Cpp17TrivialClock* requirements [[time.clock.req]].
|
| 107 |
|
| 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 |
|
| 119 |
#### In general <a id="thread.req.lockable.general">[[thread.req.lockable.general]]</a>
|
| 120 |
|
| 121 |
An *execution agent* is an entity such as a thread that may perform work
|
| 122 |
in parallel with other execution agents.
|
| 123 |
|
| 124 |
+
[*Note 1*: Implementations or users can introduce other kinds of agents
|
| 125 |
such as processes or thread-pool tasks. — *end note*]
|
| 126 |
|
| 127 |
+
The calling agent is determined by context, e.g., the calling thread
|
| 128 |
+
that contains the call, and so on.
|
| 129 |
|
| 130 |
[*Note 2*: Some lockable objects are “agent oblivious” in that they
|
| 131 |
work for any execution agent model because they do not determine or
|
| 132 |
store the agent’s ID (e.g., an ordinary spin lock). — *end note*]
|
| 133 |
|
| 134 |
+
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`).
|
| 152 |
|
| 153 |
``` cpp
|
| 154 |
m.lock()
|
|
|
|
| 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 |
|
| 173 |
+
A type `L` meets the *Cpp17Lockable* requirements if it meets the
|
| 174 |
+
*Cpp17BasicLockable* requirements and the following expressions are
|
| 175 |
well-formed and have the specified semantics (`m` denotes a value of
|
| 176 |
type `L`).
|
| 177 |
|
| 178 |
``` cpp
|
| 179 |
m.try_lock()
|
|
|
|
| 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
|
| 194 |
+
well-formed and have the specified semantics (`m` denotes a value of
|
| 195 |
+
type `L`, `rel_time` denotes a value of an instantiation of `duration`
|
| 196 |
+
[[time.duration]], and `abs_time` denotes a value of an instantiation of
|
| 197 |
+
`time_point` [[time.point]]).
|
| 198 |
|
| 199 |
``` cpp
|
| 200 |
m.try_lock_for(rel_time)
|
| 201 |
```
|
| 202 |
|
| 203 |
*Effects:* Attempts to acquire a lock for the current execution agent
|
| 204 |
+
within the relative timeout [[thread.req.timing]] specified by
|
| 205 |
+
`rel_time`. The function will not return within the timeout specified by
|
| 206 |
+
`rel_time` unless it has obtained a lock on `m` for the current
|
| 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 |
|
| 218 |
*Effects:* Attempts to acquire a lock for the current execution agent
|
| 219 |
+
before the absolute timeout [[thread.req.timing]] specified by
|
| 220 |
+
`abs_time`. The function will not return before the timeout specified by
|
| 221 |
+
`abs_time` unless it has obtained a lock on `m` for the current
|
| 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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|