From Jason Turner

[thread.req]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp7a0gz189/{from.md → to.md} +71 -80
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` ([[syserr.syserr]]). Such exceptions
14
- shall be thrown if any of the function’s error conditions is detected or
15
- a call to an operating system or other underlying API results in an
16
- error that prevents the library function from meeting its
17
- specifications. Failure to allocate storage shall be reported as
18
- described in  [[res.on.exception.handling]].
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` ([[syserr]]) and an exception of type
29
  `system_error` is thrown. — *end example*]
30
 
31
  The `error_code` reported by such an exception’s `code()` member
32
- function shall compare equal to one of the conditions specified in the
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 member functions whose names end in `_for` take an argument that
61
- specifies a duration. These functions produce relative timeouts.
62
- Implementations should use a steady clock to measure time for these
63
- functions.[^1] Given a duration argument Dₜ, the real-time duration of
64
- the timeout is Dₜ + Dᵢ + Dₘ.
65
 
66
- The member functions whose names end in `_until` take an argument that
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, i.e.
76
- Cₐ + Dᵢ + Dₘ, since the timeout is already satisfied. \[*Note 1*: This
77
  specification may result in the total duration of the wait decreasing
78
- when measured against a steady clock. — *end note*]
79
- - if Cₐ <= Cₜ, the waiting function should not time out until
80
- `Clock::now()` returns a time Cₙ >= Cₜ, i.e. waking at Cₜ + Dᵢ + Dₘ.
81
- \[*Note 2*: When the clock is adjusted backwards, this specification
82
- may result in the total duration of the wait increasing when measured
83
  against a steady clock. When the clock is adjusted forwards, this
84
- specification may result in the total duration of the wait decreasing
85
  when measured against a steady clock. — *end note*]
86
 
87
- An implementation shall return from such a timeout at any point from the
88
- time specified above to the time it would return from a steady-clock
89
- relative timeout on the difference between Cₜ and the time point of the
90
- call to the `_until` function.
91
 
92
- [*Note 3*: Implementations should decrease the duration of the wait
93
  when the clock is adjusted forwards. — *end note*]
94
 
95
- [*Note 4*: If the clock is not synchronized with a steady clock, e.g.,
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 shall
104
- meet the `TrivialClock` requirements ([[time.clock.req]]).
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 5*: Instantiations of clock, time point and duration types
112
  supplied by the implementation as specified in  [[time.clock]] do not
113
  throw exceptions. — *end note*]
114
 
115
- ### Requirements for `Lockable` types <a id="thread.req.lockable">[[thread.req.lockable]]</a>
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 may introduce other kinds of agents
123
  such as processes or thread-pool tasks. — *end note*]
124
 
125
- The calling agent is determined by context, e.g. the calling thread that
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` ([[thread.lock.unique]]),
133
- `shared_lock` ([[thread.lock.shared]]), `scoped_lock` (
134
- [[thread.lock.scoped]]), `lock_guard` ([[thread.lock.guard]]), `lock`,
135
- `try_lock` ([[thread.lock.algorithm]]), and `condition_variable_any` (
136
- [[thread.condition.condvarany]]) all operate on user-supplied lockable
137
- objects. The `BasicLockable` requirements, the `Lockable` requirements,
138
- and the `TimedLockable` requirements list the requirements imposed by
139
- these library types in order to acquire or release ownership of a `lock`
140
- by a given execution agent.
141
 
142
  [*Note 3*: The nature of any lock ownership and any synchronization it
143
- may entail are not part of these requirements. — *end note*]
144
 
145
- #### `BasicLockable` requirements <a id="thread.req.lockable.basic">[[thread.req.lockable.basic]]</a>
146
 
147
- A type `L` meets the `BasicLockable` requirements if the following
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
- *Requires:* The current execution agent shall hold a lock on `m`.
164
 
165
  *Effects:* Releases a lock on `m` held by the current execution agent.
166
 
167
  *Throws:* Nothing.
168
 
169
- #### `Lockable` requirements <a id="thread.req.lockable.req">[[thread.req.lockable.req]]</a>
170
 
171
- A type `L` meets the `Lockable` requirements if it meets the
172
- `BasicLockable` requirements and the following expressions are
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
- #### `TimedLockable` requirements <a id="thread.req.lockable.timed">[[thread.req.lockable.timed]]</a>
189
 
190
- A type `L` meets the `TimedLockable` requirements if it meets the
191
- `Lockable` requirements and the following expressions are well-formed
192
- and have the specified semantics (`m` denotes a value of type `L`,
193
- `rel_time` denotes a value of an instantiation of `duration` (
194
- [[time.duration]]), and `abs_time` denotes a value of an instantiation
195
- of `time_point` ([[time.point]])).
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 ([[thread.req.timing]]) specified by
203
- `rel_time`. The function shall not return within the timeout specified
204
- by `rel_time` unless it has obtained a lock on `m` for the current
205
- execution agent. 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, `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 ([[thread.req.timing]]) specified by
218
- `abs_time`. The function shall not return before the timeout specified
219
- by `abs_time` unless it has obtained a lock on `m` for the current
220
- execution agent. If an exception is thrown then a lock shall not have
221
- been acquired for the current execution agent.
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