From Jason Turner

[thread]

Large diff (238.9 KB) - rendering may be slow on some devices

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmptf6wslwa/{from.md → to.md} +3517 -421
tmp/tmptf6wslwa/{from.md → to.md} RENAMED
@@ -1,21 +1,22 @@
1
- # Thread support library <a id="thread">[[thread]]</a>
2
 
3
  ## General <a id="thread.general">[[thread.general]]</a>
4
 
5
  The following subclauses describe components to create and manage
6
  threads [[intro.multithread]], perform mutual exclusion, and communicate
7
  conditions and values between threads, as summarized in
8
  [[thread.summary]].
9
 
10
- **Table: Thread support library summary** <a id="thread.summary">[thread.summary]</a>
11
 
12
  | Subclause | | Header |
13
  | -------------------- | ------------------- | --------------------------- |
14
  | [[thread.req]] | Requirements | |
15
  | [[thread.stoptoken]] | Stop tokens | `<stop_token>` |
16
  | [[thread.threads]] | Threads | `<thread>` |
 
17
  | [[thread.mutex]] | Mutual exclusion | `<mutex>`, `<shared_mutex>` |
18
  | [[thread.condition]] | Condition variables | `<condition_variable>` |
19
  | [[thread.sema]] | Semaphores | `<semaphore>` |
20
  | [[thread.coord]] | Coordination types | `<latch>` `<barrier>` |
21
  | [[futures]] | Futures | `<future>` |
@@ -24,15 +25,20 @@ conditions and values between threads, as summarized in
24
  ## Requirements <a id="thread.req">[[thread.req]]</a>
25
 
26
  ### Template parameter names <a id="thread.req.paramname">[[thread.req.paramname]]</a>
27
 
28
  Throughout this Clause, the names of template parameters are used to
29
- express type requirements. If a template parameter is named `Predicate`,
30
- `operator()` applied to the template argument shall return a value that
31
- is convertible to `bool`. If a template parameter is named `Clock`, the
32
- corresponding template argument shall be a type `C` for which
33
- `is_clock_v<C>` is `true`; otherwise the program is ill-formed.
 
 
 
 
 
34
 
35
  ### Exceptions <a id="thread.req.exception">[[thread.req.exception]]</a>
36
 
37
  Some functions described in this Clause are specified to throw
38
  exceptions of type `system_error` [[syserr.syserr]]. Such exceptions are
@@ -40,11 +46,11 @@ thrown if any of the function’s error conditions is detected or a call
40
  to an operating system or other underlying API results in an error that
41
  prevents the library function from meeting its specifications. Failure
42
  to allocate storage is reported as described in 
43
  [[res.on.exception.handling]].
44
 
45
- [*Example 1*: Consider a function in this clause that is specified to
46
  throw exceptions of type `system_error` and specifies error conditions
47
  that include `operation_not_permitted` for a thread that does not have
48
  the privilege to perform the operation. Assume that, during the
49
  execution of this function, an `errno` of `EPERM` is reported by a POSIX
50
  API call used by the implementation. Since POSIX specifies an `errno` of
@@ -82,12 +88,13 @@ and memory resources induces a “quality of management” delay, expressed
82
  as duration Dₘ. The delay durations may vary from timeout to timeout,
83
  but in all cases shorter is better.
84
 
85
  The functions whose names end in `_for` take an argument that specifies
86
  a duration. These functions produce relative timeouts. Implementations
87
- should use a steady clock to measure time for these functions.[^1] Given
88
- a duration argument Dₜ, the real-time duration of the timeout is
 
89
  Dₜ + Dᵢ + Dₘ.
90
 
91
  The functions whose names end in `_until` take an argument that
92
  specifies a time point. These functions produce absolute timeouts.
93
  Implementations should use the clock specified in the time point to
@@ -95,15 +102,15 @@ measure time for these functions. Given a clock time point argument Cₜ,
95
  the clock time point of the return from timeout should be Cₜ + Dᵢ + Dₘ
96
  when the clock is not adjusted during the timeout. If the clock is
97
  adjusted to the time Cₐ during the timeout, the behavior should be as
98
  follows:
99
 
100
- - if Cₐ > Cₜ, the waiting function should wake as soon as possible,
101
  i.e., Cₐ + Dᵢ + Dₘ, since the timeout is already satisfied. This
102
  specification may result in the total duration of the wait decreasing
103
  when measured against a steady clock.
104
- - if Cₐ ≤ Cₜ, the waiting function should not time out until
105
  `Clock::now()` returns a time Cₙ ≥ Cₜ, i.e., waking at Cₜ + Dᵢ + Dₘ.
106
  \[*Note 1*: When the clock is adjusted backwards, this specification
107
  can result in the total duration of the wait increasing when measured
108
  against a steady clock. When the clock is adjusted forwards, this
109
  specification can result in the total duration of the wait decreasing
@@ -112,15 +119,15 @@ follows:
112
  An implementation returns from such a timeout at any point from the time
113
  specified above to the time it would return from a steady-clock relative
114
  timeout on the difference between Cₜ and the time point of the call to
115
  the `_until` function.
116
 
117
- [*Note 2*: Implementations should decrease the duration of the wait
118
- when the clock is adjusted forwards. — *end note*]
119
 
120
- [*Note 3*: If the clock is not synchronized with a steady clock, e.g.,
121
- a CPU time clock, these timeouts might not provide useful
122
  functionality. — *end note*]
123
 
124
  The resolution of timing provided by an implementation depends on both
125
  operating system and hardware. The finest resolution provided by an
126
  implementation is called the *native resolution*.
@@ -131,11 +138,11 @@ the *Cpp17TrivialClock* requirements [[time.clock.req]].
131
  A function that takes an argument which specifies a timeout will throw
132
  if, during its execution, a clock, time point, or time duration throws
133
  an exception. Such exceptions are referred to as *timeout-related
134
  exceptions*.
135
 
136
- [*Note 4*: Instantiations of clock, time point and duration types
137
  supplied by the implementation as specified in  [[time.clock]] do not
138
  throw exceptions. — *end note*]
139
 
140
  ### Requirements for *Cpp17Lockable* types <a id="thread.req.lockable">[[thread.req.lockable]]</a>
141
 
@@ -158,17 +165,31 @@ The standard library templates `unique_lock` [[thread.lock.unique]],
158
  `shared_lock` [[thread.lock.shared]], `scoped_lock`
159
  [[thread.lock.scoped]], `lock_guard` [[thread.lock.guard]], `lock`,
160
  `try_lock` [[thread.lock.algorithm]], and `condition_variable_any`
161
  [[thread.condition.condvarany]] all operate on user-supplied lockable
162
  objects. The *Cpp17BasicLockable* requirements, the *Cpp17Lockable*
163
- requirements, and the *Cpp17TimedLockable* requirements list the
164
- requirements imposed by these library types in order to acquire or
165
- release ownership of a `lock` by a given execution agent.
 
 
166
 
167
  [*Note 3*: The nature of any lock ownership and any synchronization it
168
  entails are not part of these requirements. — *end note*]
169
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  #### *Cpp17BasicLockable* requirements <a id="thread.req.lockable.basic">[[thread.req.lockable.basic]]</a>
171
 
172
  A type `L` meets the *Cpp17BasicLockable* requirements if the following
173
  expressions are well-formed and have the specified semantics (`m`
174
  denotes a value of type `L`).
@@ -183,13 +204,15 @@ acquired for the current execution agent.
183
 
184
  ``` cpp
185
  m.unlock()
186
  ```
187
 
188
- *Preconditions:* The current execution agent holds a lock on `m`.
 
189
 
190
- *Effects:* Releases a lock on `m` held by the current execution agent.
 
191
 
192
  *Throws:* Nothing.
193
 
194
  #### *Cpp17Lockable* requirements <a id="thread.req.lockable.req">[[thread.req.lockable.req]]</a>
195
 
@@ -206,11 +229,11 @@ m.try_lock()
206
  without blocking. If an exception is thrown then a lock shall not have
207
  been acquired for the current execution agent.
208
 
209
  *Return type:* `bool`.
210
 
211
- *Returns:* `true` if the lock was acquired, `false` otherwise.
212
 
213
  #### *Cpp17TimedLockable* requirements <a id="thread.req.lockable.timed">[[thread.req.lockable.timed]]</a>
214
 
215
  A type `L` meets the *Cpp17TimedLockable* requirements if it meets the
216
  *Cpp17Lockable* requirements and the following expressions are
@@ -230,11 +253,11 @@ within the relative timeout [[thread.req.timing]] specified by
230
  execution agent. If an exception is thrown then a lock has not been
231
  acquired for the current execution agent.
232
 
233
  *Return type:* `bool`.
234
 
235
- *Returns:* `true` if the lock was acquired, `false` otherwise.
236
 
237
  ``` cpp
238
  m.try_lock_until(abs_time)
239
  ```
240
 
@@ -245,20 +268,91 @@ before the absolute timeout [[thread.req.timing]] specified by
245
  execution agent. If an exception is thrown then a lock has not been
246
  acquired for the current execution agent.
247
 
248
  *Return type:* `bool`.
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  *Returns:* `true` if the lock was acquired, `false` otherwise.
251
 
252
  ## Stop tokens <a id="thread.stoptoken">[[thread.stoptoken]]</a>
253
 
254
  ### Introduction <a id="thread.stoptoken.intro">[[thread.stoptoken.intro]]</a>
255
 
256
- This clause describes components that can be used to asynchonously
257
- request that an operation stops execution in a timely manner, typically
258
- because the result is no longer required. Such a request is called a
259
- *stop request*.
260
 
261
  `stop_source`, `stop_token`, and `stop_callback` implement semantics of
262
  shared ownership of a *stop state*. Any `stop_source`, `stop_token`, or
263
  `stop_callback` that shares ownership of the same stop state is an
264
  *associated* `stop_source`, `stop_token`, or `stop_callback`,
@@ -300,22 +394,24 @@ namespace std {
300
  struct nostopstate_t {
301
  explicit nostopstate_t() = default;
302
  };
303
  inline constexpr nostopstate_t nostopstate{};
304
 
305
- // [stopcallback], class stop_callback
306
  template<class Callback>
307
  class stop_callback;
308
  }
309
  ```
310
 
311
  ### Class `stop_token` <a id="stoptoken">[[stoptoken]]</a>
312
 
 
 
313
  The class `stop_token` provides an interface for querying whether a stop
314
  request has been made (`stop_requested`) or can ever be made
315
- (`stop_possible`) using an associated `stop_source` object (
316
- [[stopsource]]). A `stop_token` can also be passed to a `stop_callback`
317
  [[stopcallback]] constructor to register a callback to be called when a
318
  stop request has been made from an associated `stop_source`.
319
 
320
  ``` cpp
321
  namespace std {
@@ -435,14 +531,16 @@ friend void swap(stop_token& x, stop_token& y) noexcept;
435
 
436
  *Effects:* Equivalent to: `x.swap(y)`.
437
 
438
  ### Class `stop_source` <a id="stopsource">[[stopsource]]</a>
439
 
 
 
440
  The class `stop_source` implements the semantics of making a stop
441
  request. A stop request made on a `stop_source` object is visible to all
442
- associated `stop_source` and `stop_token` ([[stoptoken]]) objects. Once
443
- a stop request has been made it cannot be withdrawn (a subsequent stop
444
  request has no effect).
445
 
446
  ``` cpp
447
  namespace std {
448
  // no-shared-stop-state indicator
@@ -486,12 +584,11 @@ stop_source();
486
  *Effects:* Initialises `*this` to have ownership of a new stop state.
487
 
488
  *Ensures:* `stop_possible()` is `true` and `stop_requested()` is
489
  `false`.
490
 
491
- *Throws:* `bad_alloc` if memory could not be allocated for the stop
492
- state.
493
 
494
  ``` cpp
495
  explicit stop_source(nostopstate_t) noexcept;
496
  ```
497
 
@@ -576,11 +673,11 @@ bool request_stop() noexcept;
576
  has received a stop request, and if not, makes a stop request. The
577
  determination and making of the stop request are an atomic
578
  read-modify-write operation [[intro.races]]. If the request was made,
579
  the callbacks registered by associated `stop_callback` objects are
580
  synchronously called. If an invocation of a callback exits via an
581
- exception then `terminate` is called [[except.terminate]].
582
 
583
  [*Note 1*: A stop request includes notifying all condition variables of
584
  type `condition_variable_any` temporarily registered during an
585
  interruptible wait [[thread.condvarany.intwait]]. — *end note*]
586
 
@@ -605,10 +702,12 @@ friend void swap(stop_source& x, stop_source& y) noexcept;
605
 
606
  *Effects:* Equivalent to: `x.swap(y)`.
607
 
608
  ### Class template `stop_callback` <a id="stopcallback">[[stopcallback]]</a>
609
 
 
 
610
  ``` cpp
611
  namespace std {
612
  template<class Callback>
613
  class stop_callback {
614
  public:
@@ -669,15 +768,15 @@ before the constructor returns. Otherwise, if `st` has ownership of a
669
  stop state, acquires shared ownership of that stop state and registers
670
  the callback with that stop state such that
671
  `std::forward<Callback>(callback)()` is evaluated by the first call to
672
  `request_stop()` on an associated `stop_source`.
673
 
674
- *Remarks:* If evaluating `std::forward<Callback>(callback)()` exits via
675
- an exception, then `terminate` is called [[except.terminate]].
676
-
677
  *Throws:* Any exception thrown by the initialization of `callback`.
678
 
 
 
 
679
  ``` cpp
680
  ~stop_callback();
681
  ```
682
 
683
  *Effects:* Unregisters the callback from the owned stop state, if any.
@@ -690,30 +789,33 @@ thread, then the destructor does not block [[defns.block]] waiting for
690
  the return from the invocation of `callback`. Releases ownership of the
691
  stop state, if any.
692
 
693
  ## Threads <a id="thread.threads">[[thread.threads]]</a>
694
 
 
 
695
  [[thread.threads]] describes components that can be used to create and
696
  manage threads.
697
 
698
  [*Note 1*: These threads are intended to map one-to-one with operating
699
  system threads. — *end note*]
700
 
701
  ### Header `<thread>` synopsis <a id="thread.syn">[[thread.syn]]</a>
702
 
703
  ``` cpp
704
  #include <compare> // see [compare.syn]
705
- #include <initializer_list> // see [initializer.list.syn]
706
 
707
  namespace std {
 
708
  class thread;
709
 
710
  void swap(thread& x, thread& y) noexcept;
711
 
712
- // [thread.jthread.class] class jthread
713
  class jthread;
714
 
 
715
  namespace this_thread {
716
  thread::id get_id() noexcept;
717
 
718
  void yield() noexcept;
719
  template<class Clock, class Duration>
@@ -724,10 +826,12 @@ namespace std {
724
  }
725
  ```
726
 
727
  ### Class `thread` <a id="thread.thread.class">[[thread.thread.class]]</a>
728
 
 
 
729
  The class `thread` provides a mechanism to create a new thread of
730
  execution, to join with a thread (i.e., wait for a thread to complete),
731
  and to perform other operations that manage and query the state of a
732
  thread. A `thread` object uniquely represents a particular thread of
733
  execution. That representation may be transferred to other `thread`
@@ -743,11 +847,11 @@ successful call to `detach` or `join`. — *end note*]
743
 
744
  ``` cpp
745
  namespace std {
746
  class thread {
747
  public:
748
- // types
749
  class id;
750
  using native_handle_type = implementation-defined; // see~[thread.req.native]
751
 
752
  // construct/copy/destroy
753
  thread() noexcept;
@@ -756,11 +860,11 @@ namespace std {
756
  thread(const thread&) = delete;
757
  thread(thread&&) noexcept;
758
  thread& operator=(const thread&) = delete;
759
  thread& operator=(thread&&) noexcept;
760
 
761
- // members
762
  void swap(thread&) noexcept;
763
  bool joinable() const noexcept;
764
  void join();
765
  void detach();
766
  id get_id() const noexcept;
@@ -786,10 +890,12 @@ namespace std {
786
 
787
  template<class charT, class traits>
788
  basic_ostream<charT, traits>&
789
  operator<<(basic_ostream<charT, traits>& out, thread::id id);
790
 
 
 
791
  // hash support
792
  template<class T> struct hash;
793
  template<> struct hash<thread::id>;
794
  }
795
  ```
@@ -800,10 +906,16 @@ that do not represent a thread of execution [[thread.thread.class]].
800
  Each thread of execution has an associated `thread::id` object that is
801
  not equal to the `thread::id` object of any other thread of execution
802
  and that is not equal to the `thread::id` object of any `thread` object
803
  that does not represent threads of execution.
804
 
 
 
 
 
 
 
805
  `thread::id` is a trivially copyable class [[class.prop]]. The library
806
  may reuse the value of a `thread::id` of a terminated thread that can no
807
  longer be joined.
808
 
809
  [*Note 1*: Relational operators allow `thread::id` objects to be used
@@ -838,17 +950,37 @@ described in [[alg.sorting]].
838
  template<class charT, class traits>
839
  basic_ostream<charT, traits>&
840
  operator<< (basic_ostream<charT, traits>& out, thread::id id);
841
  ```
842
 
843
- *Effects:* Inserts an unspecified text representation of `id` into
844
- `out`. For two objects of type `thread::id` `x` and `y`, if `x == y` the
845
- `thread::id` objects have the same text representation and if `x != y`
846
- the `thread::id` objects have distinct text representations.
847
 
848
  *Returns:* `out`.
849
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
850
  ``` cpp
851
  template<> struct hash<thread::id>;
852
  ```
853
 
854
  The specialization is enabled [[unord.hash]].
@@ -870,33 +1002,30 @@ template<class F, class... Args> explicit thread(F&& f, Args&&... args);
870
  *Constraints:* `remove_cvref_t<F>` is not the same type as `thread`.
871
 
872
  *Mandates:* The following are all `true`:
873
 
874
  - `is_constructible_v<decay_t<F>, F>`,
875
- - `(is_constructible_v<decay_t<Args>, Args> && ...)`,
876
- - `is_move_constructible_v<decay_t<F>>`,
877
- - `(is_move_constructible_v<decay_t<Args>> && ...)`, and
878
  - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
879
 
880
- *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
881
- *Cpp17MoveConstructible* requirements.
882
-
883
  *Effects:* The new thread of execution executes
884
 
885
  ``` cpp
886
- invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
 
887
  ```
888
 
889
- with the calls to *`decay-copy`* being evaluated in the constructing
890
- thread. Any return value from this invocation is ignored.
 
891
 
892
  [*Note 1*: This implies that any exceptions not thrown from the
893
  invocation of the copy of `f` will be thrown in the constructing thread,
894
  not the new thread. — *end note*]
895
 
896
  If the invocation of `invoke` terminates with an uncaught exception,
897
- `terminate` is called.
898
 
899
  *Synchronization:* The completion of the invocation of the constructor
900
  synchronizes with the beginning of the invocation of the copy of `f`.
901
 
902
  *Ensures:* `get_id() != id()`. `*this` represents the newly started
@@ -921,27 +1050,29 @@ thread(thread&& x) noexcept;
921
 
922
  ``` cpp
923
  ~thread();
924
  ```
925
 
926
- *Effects:* If `joinable()`, calls `terminate()`. Otherwise, has no
927
- effects.
928
 
929
  [*Note 1*: Either implicitly detaching or joining a `joinable()` thread
930
- in its destructor could result in difficult to debug correctness (for
931
  detach) or performance (for join) bugs encountered only when an
932
- exception is thrown. Thus the programmer must ensure that the destructor
933
- is never executed while the thread is still joinable. — *end note*]
 
934
 
935
  #### Assignment <a id="thread.thread.assign">[[thread.thread.assign]]</a>
936
 
937
  ``` cpp
938
  thread& operator=(thread&& x) noexcept;
939
  ```
940
 
941
- *Effects:* If `joinable()`, calls `terminate()`. Otherwise, assigns the
942
- state of `x` to `*this` and sets `x` to a default constructed state.
 
943
 
944
  *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
945
  `x.get_id()` prior to the assignment.
946
 
947
  *Returns:* `*this`.
@@ -1035,10 +1166,12 @@ void swap(thread& x, thread& y) noexcept;
1035
 
1036
  *Effects:* As if by `x.swap(y)`.
1037
 
1038
  ### Class `jthread` <a id="thread.jthread.class">[[thread.jthread.class]]</a>
1039
 
 
 
1040
  The class `jthread` provides a mechanism to create a new thread of
1041
  execution. The functionality is the same as for class `thread`
1042
  [[thread.thread.class]] with the additional abilities to provide a
1043
  `stop_token` [[thread.stoptoken]] to the new thread of execution, make
1044
  stop requests, and automatically join.
@@ -1104,34 +1237,30 @@ template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
1104
  *Constraints:* `remove_cvref_t<F>` is not the same type as `jthread`.
1105
 
1106
  *Mandates:* The following are all `true`:
1107
 
1108
  - `is_constructible_v<decay_t<F>, F>`,
1109
- - `(is_constructible_v<decay_t<Args>, Args> && ...)`,
1110
- - `is_move_constructible_v<decay_t<F>>`,
1111
- - `(is_move_constructible_v<decay_t<Args>> && ...)`, and
1112
  - `is_invocable_v<decay_t<F>, decay_t<Args>...> ||`
1113
  `is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>`.
1114
 
1115
- *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
1116
- *Cpp17MoveConstructible* requirements.
1117
-
1118
  *Effects:* Initializes `ssource`. The new thread of execution executes
1119
 
1120
  ``` cpp
1121
- invoke(decay-copy(std::forward<F>(f)), get_stop_token(),
1122
- decay-copy(std::forward<Args>(args))...)
1123
  ```
1124
 
1125
  if that expression is well-formed, otherwise
1126
 
1127
  ``` cpp
1128
- invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
1129
  ```
1130
 
1131
- with the calls to *`decay-copy`* being evaluated in the constructing
1132
- thread. Any return value from this invocation is ignored.
 
1133
 
1134
  [*Note 1*: This implies that any exceptions not thrown from the
1135
  invocation of the copy of `f` will be thrown in the constructing thread,
1136
  not the new thread. — *end note*]
1137
 
@@ -1175,18 +1304,18 @@ of `x.ssource` prior to the start of construction and
1175
 
1176
  ``` cpp
1177
  jthread& operator=(jthread&& x) noexcept;
1178
  ```
1179
 
1180
- *Effects:* If `joinable()` is `true`, calls `request_stop()` and then
1181
- `join()`. Assigns the state of `x` to `*this` and sets `x` to a default
 
1182
  constructed state.
1183
 
1184
- *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
1185
- `x.get_id()` prior to the assignment. `ssource` has the value of
1186
- `x.ssource` prior to the assignment and `x.ssource.stop_possible()` is
1187
- `false`.
1188
 
1189
  *Returns:* `*this`.
1190
 
1191
  #### Members <a id="thread.jthread.mem">[[thread.jthread.mem]]</a>
1192
 
@@ -1308,13 +1437,13 @@ namespace std::this_thread {
1308
  ``` cpp
1309
  thread::id this_thread::get_id() noexcept;
1310
  ```
1311
 
1312
  *Returns:* An object of type `thread::id` that uniquely identifies the
1313
- current thread of execution. No other thread of execution has this id
1314
- and this thread of execution always has this id. The object returned
1315
- does not compare equal to a default constructed `thread::id`.
1316
 
1317
  ``` cpp
1318
  void this_thread::yield() noexcept;
1319
  ```
1320
 
@@ -1344,40 +1473,2886 @@ timeout [[thread.req.timing]] specified by `rel_time`.
1344
 
1345
  *Synchronization:* None.
1346
 
1347
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
1348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1349
  ## Mutual exclusion <a id="thread.mutex">[[thread.mutex]]</a>
1350
 
1351
- This subclause provides mechanisms for mutual exclusion: mutexes, locks,
1352
- and call once. These mechanisms ease the production of race-free
1353
- programs [[intro.multithread]].
 
 
1354
 
1355
  ### Header `<mutex>` synopsis <a id="mutex.syn">[[mutex.syn]]</a>
1356
 
1357
  ``` cpp
1358
  namespace std {
 
1359
  class mutex;
 
1360
  class recursive_mutex;
 
1361
  class timed_mutex;
 
1362
  class recursive_timed_mutex;
1363
 
1364
  struct defer_lock_t { explicit defer_lock_t() = default; };
1365
  struct try_to_lock_t { explicit try_to_lock_t() = default; };
1366
  struct adopt_lock_t { explicit adopt_lock_t() = default; };
1367
 
1368
  inline constexpr defer_lock_t defer_lock { };
1369
  inline constexpr try_to_lock_t try_to_lock { };
1370
  inline constexpr adopt_lock_t adopt_lock { };
1371
 
 
1372
  template<class Mutex> class lock_guard;
1373
  template<class... MutexTypes> class scoped_lock;
1374
  template<class Mutex> class unique_lock;
1375
 
1376
  template<class Mutex>
1377
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
1378
 
 
1379
  template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
1380
  template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
1381
 
1382
  struct once_flag;
1383
 
@@ -1388,12 +4363,15 @@ namespace std {
1388
 
1389
  ### Header `<shared_mutex>` synopsis <a id="shared.mutex.syn">[[shared.mutex.syn]]</a>
1390
 
1391
  ``` cpp
1392
  namespace std {
 
1393
  class shared_mutex;
 
1394
  class shared_timed_mutex;
 
1395
  template<class Mutex> class shared_lock;
1396
  template<class Mutex>
1397
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
1398
  }
1399
  ```
@@ -1410,18 +4388,20 @@ Mutexes can be either recursive or non-recursive, and can grant
1410
  simultaneous ownership to one or many execution agents. Both recursive
1411
  and non-recursive mutexes are supplied.
1412
 
1413
  #### Mutex types <a id="thread.mutex.requirements.mutex">[[thread.mutex.requirements.mutex]]</a>
1414
 
 
 
1415
  The *mutex types* are the standard library types `mutex`,
1416
  `recursive_mutex`, `timed_mutex`, `recursive_timed_mutex`,
1417
  `shared_mutex`, and `shared_timed_mutex`. They meet the requirements set
1418
- out in this subclause. In this description, `m` denotes an object of a
1419
- mutex type.
1420
 
1421
- The mutex types meet the *Cpp17Lockable* requirements
1422
- [[thread.req.lockable.req]].
1423
 
1424
  The mutex types meet *Cpp17DefaultConstructible* and
1425
  *Cpp17Destructible*. If initialization of an object of a mutex type
1426
  fails, an exception of type `system_error` is thrown. The mutex types
1427
  are neither copyable nor movable.
@@ -1439,15 +4419,15 @@ functions of the mutex types are as follows:
1439
  The implementation provides lock and unlock operations, as described
1440
  below. For purposes of determining the existence of a data race, these
1441
  behave as atomic operations [[intro.multithread]]. The lock and unlock
1442
  operations on a single mutex appears to occur in a single total order.
1443
 
1444
- [*Note 1*: This can be viewed as the modification order
1445
  [[intro.multithread]] of the mutex. — *end note*]
1446
 
1447
- [*Note 2*: Construction and destruction of an object of a mutex type
1448
- need not be thread-safe; other synchronization should be used to ensure
1449
  that mutex objects are initialized and visible to other
1450
  threads. — *end note*]
1451
 
1452
  The expression `m.lock()` is well-formed and has the following
1453
  semantics:
@@ -1457,17 +4437,17 @@ semantics:
1457
  the mutex.
1458
 
1459
  *Effects:* Blocks the calling thread until ownership of the mutex can be
1460
  obtained for the calling thread.
1461
 
1462
- *Ensures:* The calling thread owns the mutex.
1463
-
1464
- *Return type:* `void`.
1465
-
1466
  *Synchronization:* Prior `unlock()` operations on the same object
1467
  *synchronize with*[[intro.multithread]] this operation.
1468
 
 
 
 
 
1469
  *Throws:* `system_error` when an exception is
1470
  required [[thread.req.exception]].
1471
 
1472
  *Error conditions:*
1473
 
@@ -1493,24 +4473,23 @@ interesting implementations based on a simple compare and
1493
  exchange [[atomics]]. — *end note*]
1494
 
1495
  An implementation should ensure that `try_lock()` does not consistently
1496
  return `false` in the absence of contending mutex acquisitions.
1497
 
1498
- *Return type:* `bool`.
1499
-
1500
- *Returns:* `true` if ownership of the mutex was obtained for the calling
1501
- thread, otherwise `false`.
1502
-
1503
  *Synchronization:* If `try_lock()` returns `true`, prior `unlock()`
1504
  operations on the same object *synchronize with*[[intro.multithread]]
1505
  this operation.
1506
 
1507
  [*Note 2*: Since `lock()` does not synchronize with a failed subsequent
1508
  `try_lock()`, the visibility rules are weak enough that little would be
1509
  known about the state after a failure, even in the absence of spurious
1510
  failures. — *end note*]
1511
 
 
 
 
 
1512
  *Throws:* Nothing.
1513
 
1514
  The expression `m.unlock()` is well-formed and has the following
1515
  semantics:
1516
 
@@ -1552,11 +4531,11 @@ The class `mutex` provides a non-recursive mutex with exclusive
1552
  ownership semantics. If one thread owns a mutex object, attempts by
1553
  another thread to acquire ownership of that object will fail (for
1554
  `try_lock()`) or block (for `lock()`) until the owning thread has
1555
  released ownership with a call to `unlock()`.
1556
 
1557
- [*Note 3*: After a thread `A` has called `unlock()`, releasing a mutex,
1558
  it is possible for another thread `B` to lock the same mutex, observe
1559
  that it is no longer in use, unlock it, and destroy it, before thread
1560
  `A` appears to have returned from its unlock call. Implementations are
1561
  required to handle such scenarios correctly, as long as thread `A`
1562
  doesn’t access the mutex after the unlock call returns. These cases
@@ -1565,11 +4544,11 @@ used to protect the reference count. — *end note*]
1565
 
1566
  The class `mutex` meets all of the mutex requirements
1567
  [[thread.mutex.requirements]]. It is a standard-layout class
1568
  [[class.prop]].
1569
 
1570
- [*Note 4*: A program can deadlock if the thread that owns a `mutex`
1571
  object calls `lock()` on that object. If the implementation can detect
1572
  the deadlock, a `resource_deadlock_would_occur` error condition might be
1573
  observed. — *end note*]
1574
 
1575
  The behavior of a program is undefined if it destroys a `mutex` object
@@ -1624,19 +4603,21 @@ The behavior of a program is undefined if:
1624
  - it destroys a `recursive_mutex` object owned by any thread or
1625
  - a thread terminates while owning a `recursive_mutex` object.
1626
 
1627
  #### Timed mutex types <a id="thread.timedmutex.requirements">[[thread.timedmutex.requirements]]</a>
1628
 
 
 
1629
  The *timed mutex types* are the standard library types `timed_mutex`,
1630
  `recursive_timed_mutex`, and `shared_timed_mutex`. They meet the
1631
  requirements set out below. In this description, `m` denotes an object
1632
  of a mutex type, `rel_time` denotes an object of an instantiation of
1633
  `duration` [[time.duration]], and `abs_time` denotes an object of an
1634
  instantiation of `time_point` [[time.point]].
1635
 
1636
- The timed mutex types meet the *Cpp17TimedLockable* requirements
1637
- [[thread.req.lockable.timed]].
1638
 
1639
  The expression `m.try_lock_for(rel_time)` is well-formed and has the
1640
  following semantics:
1641
 
1642
  *Preconditions:* If `m` is of type `timed_mutex` or
@@ -1652,18 +4633,18 @@ the mutex object.
1652
 
1653
  [*Note 1*: As with `try_lock()`, there is no guarantee that ownership
1654
  will be obtained if the lock is available, but implementations are
1655
  expected to make a strong effort to do so. — *end note*]
1656
 
1657
- *Return type:* `bool`.
1658
-
1659
- *Returns:* `true` if ownership was obtained, otherwise `false`.
1660
-
1661
  *Synchronization:* If `try_lock_for()` returns `true`, prior `unlock()`
1662
  operations on the same object *synchronize with*[[intro.multithread]]
1663
  this operation.
1664
 
 
 
 
 
1665
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
1666
 
1667
  The expression `m.try_lock_until(abs_time)` is well-formed and has the
1668
  following semantics:
1669
 
@@ -1678,18 +4659,18 @@ before the absolute timeout [[thread.req.timing]] specified by
1678
 
1679
  [*Note 2*: As with `try_lock()`, there is no guarantee that ownership
1680
  will be obtained if the lock is available, but implementations are
1681
  expected to make a strong effort to do so. — *end note*]
1682
 
1683
- *Return type:* `bool`.
1684
-
1685
- *Returns:* `true` if ownership was obtained, otherwise `false`.
1686
-
1687
  *Synchronization:* If `try_lock_until()` returns `true`, prior
1688
  `unlock()` operations on the same object *synchronize
1689
  with*[[intro.multithread]] this operation.
1690
 
 
 
 
 
1691
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
1692
 
1693
  ##### Class `timed_mutex` <a id="thread.timedmutex.class">[[thread.timedmutex.class]]</a>
1694
 
1695
  ``` cpp
@@ -1792,16 +4773,21 @@ The behavior of a program is undefined if:
1792
  - it destroys a `recursive_timed_mutex` object owned by any thread, or
1793
  - a thread terminates while owning a `recursive_timed_mutex` object.
1794
 
1795
  #### Shared mutex types <a id="thread.sharedmutex.requirements">[[thread.sharedmutex.requirements]]</a>
1796
 
 
 
1797
  The standard library types `shared_mutex` and `shared_timed_mutex` are
1798
  *shared mutex types*. Shared mutex types meet the requirements of mutex
1799
  types [[thread.mutex.requirements.mutex]] and additionally meet the
1800
  requirements set out below. In this description, `m` denotes an object
1801
  of a shared mutex type.
1802
 
 
 
 
1803
  In addition to the exclusive lock ownership mode specified in 
1804
  [[thread.mutex.requirements.mutex]], shared mutex types provide a
1805
  *shared lock* ownership mode. Multiple execution agents can
1806
  simultaneously hold a shared lock ownership of a shared mutex type. But
1807
  no execution agent holds a shared lock while another execution agent
@@ -1820,17 +4806,17 @@ semantics:
1820
 
1821
  *Effects:* Blocks the calling thread until shared ownership of the mutex
1822
  can be obtained for the calling thread. If an exception is thrown then a
1823
  shared lock has not been acquired for the current thread.
1824
 
1825
- *Ensures:* The calling thread has a shared lock on the mutex.
1826
-
1827
- *Return type:* `void`.
1828
-
1829
  *Synchronization:* Prior `unlock()` operations on the same object
1830
  synchronize with [[intro.multithread]] this operation.
1831
 
 
 
 
 
1832
  *Throws:* `system_error` when an exception is
1833
  required [[thread.req.exception]].
1834
 
1835
  *Error conditions:*
1836
 
@@ -1864,19 +4850,18 @@ following semantics:
1864
  calling thread without blocking. If shared ownership is not obtained,
1865
  there is no effect and `try_lock_shared()` immediately returns. An
1866
  implementation may fail to obtain the lock even if it is not held by any
1867
  other thread.
1868
 
1869
- *Return type:* `bool`.
1870
-
1871
- *Returns:* `true` if the shared ownership lock was acquired, `false`
1872
- otherwise.
1873
-
1874
  *Synchronization:* If `try_lock_shared()` returns `true`, prior
1875
  `unlock()` operations on the same object synchronize
1876
  with [[intro.multithread]] this operation.
1877
 
 
 
 
 
1878
  *Throws:* Nothing.
1879
 
1880
  ##### Class `shared_mutex` <a id="thread.sharedmutex.class">[[thread.sharedmutex.class]]</a>
1881
 
1882
  ``` cpp
@@ -1922,19 +4907,25 @@ The behavior of a program is undefined if:
1922
 
1923
  `shared_mutex` may be a synonym for `shared_timed_mutex`.
1924
 
1925
  #### Shared timed mutex types <a id="thread.sharedtimedmutex.requirements">[[thread.sharedtimedmutex.requirements]]</a>
1926
 
 
 
1927
  The standard library type `shared_timed_mutex` is a *shared timed mutex
1928
  type*. Shared timed mutex types meet the requirements of timed mutex
1929
  types [[thread.timedmutex.requirements]], shared mutex types
1930
  [[thread.sharedmutex.requirements]], and additionally meet the
1931
  requirements set out below. In this description, `m` denotes an object
1932
- of a shared timed mutex type, `rel_type` denotes an object of an
1933
  instantiation of `duration` [[time.duration]], and `abs_time` denotes an
1934
  object of an instantiation of `time_point` [[time.point]].
1935
 
 
 
 
 
1936
  The expression `m.try_lock_shared_for(rel_time)` is well-formed and has
1937
  the following semantics:
1938
 
1939
  *Preconditions:* The calling thread has no ownership of the mutex.
1940
 
@@ -1951,18 +4942,18 @@ will be obtained if the lock is available, but implementations are
1951
  expected to make a strong effort to do so. — *end note*]
1952
 
1953
  If an exception is thrown then a shared lock has not been acquired for
1954
  the current thread.
1955
 
1956
- *Return type:* `bool`.
1957
-
1958
- *Returns:* `true` if the shared lock was acquired, `false` otherwise.
1959
-
1960
  *Synchronization:* If `try_lock_shared_for()` returns `true`, prior
1961
  `unlock()` operations on the same object synchronize
1962
  with [[intro.multithread]] this operation.
1963
 
 
 
 
 
1964
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
1965
 
1966
  The expression `m.try_lock_shared_until(abs_time)` is well-formed and
1967
  has the following semantics:
1968
 
@@ -1980,18 +4971,18 @@ will be obtained if the lock is available, but implementations are
1980
  expected to make a strong effort to do so. — *end note*]
1981
 
1982
  If an exception is thrown then a shared lock has not been acquired for
1983
  the current thread.
1984
 
1985
- *Return type:* `bool`.
1986
-
1987
- *Returns:* `true` if the shared lock was acquired, `false` otherwise.
1988
-
1989
  *Synchronization:* If `try_lock_shared_until()` returns `true`, prior
1990
  `unlock()` operations on the same object synchronize
1991
  with [[intro.multithread]] this operation.
1992
 
 
 
 
 
1993
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
1994
 
1995
  ##### Class `shared_timed_mutex` <a id="thread.sharedtimedmutex.class">[[thread.sharedtimedmutex.class]]</a>
1996
 
1997
  ``` cpp
@@ -2040,10 +5031,12 @@ The behavior of a program is undefined if:
2040
  - a thread terminates while possessing any ownership of a
2041
  `shared_timed_mutex`.
2042
 
2043
  ### Locks <a id="thread.lock">[[thread.lock]]</a>
2044
 
 
 
2045
  A *lock* is an object that holds a reference to a lockable object and
2046
  may unlock the lockable object during the lock’s destruction (such as
2047
  when leaving block scope). An execution agent may use a lock to aid in
2048
  managing ownership of a lockable object in an exception safe manner. A
2049
  lock is said to *own* a lockable object if it is currently managing the
@@ -2103,39 +5096,36 @@ object referenced by `pm` does not exist for the entire lifetime of the
2103
 
2104
  ``` cpp
2105
  explicit lock_guard(mutex_type& m);
2106
  ```
2107
 
2108
- *Preconditions:* If `mutex_type` is not a recursive mutex, the calling
2109
- thread does not own the mutex `m`.
2110
-
2111
  *Effects:* Initializes `pm` with `m`. Calls `m.lock()`.
2112
 
2113
  ``` cpp
2114
  lock_guard(mutex_type& m, adopt_lock_t);
2115
  ```
2116
 
2117
- *Preconditions:* The calling thread owns the mutex `m`.
2118
 
2119
  *Effects:* Initializes `pm` with `m`.
2120
 
2121
  *Throws:* Nothing.
2122
 
2123
  ``` cpp
2124
  ~lock_guard();
2125
  ```
2126
 
2127
- *Effects:* As if by `pm.unlock()`.
2128
 
2129
  #### Class template `scoped_lock` <a id="thread.lock.scoped">[[thread.lock.scoped]]</a>
2130
 
2131
  ``` cpp
2132
  namespace std {
2133
  template<class... MutexTypes>
2134
  class scoped_lock {
2135
  public:
2136
- using mutex_type = Mutex; // If MutexTypes... consists of the single type Mutex
2137
 
2138
  explicit scoped_lock(MutexTypes&... m);
2139
  explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
2140
  ~scoped_lock();
2141
 
@@ -2151,32 +5141,35 @@ namespace std {
2151
  An object of type `scoped_lock` controls the ownership of lockable
2152
  objects within a scope. A `scoped_lock` object maintains ownership of
2153
  lockable objects throughout the `scoped_lock` object’s lifetime
2154
  [[basic.life]]. The behavior of a program is undefined if the lockable
2155
  objects referenced by `pm` do not exist for the entire lifetime of the
2156
- `scoped_lock` object. When `sizeof...(MutexTypes)` is `1`, the supplied
2157
- `Mutex` type shall meet the *Cpp17BasicLockable* requirements
2158
- [[thread.req.lockable.basic]]. Otherwise, each of the mutex types shall
2159
- meet the *Cpp17Lockable* requirements [[thread.req.lockable.req]].
 
 
 
 
 
2160
 
2161
  ``` cpp
2162
  explicit scoped_lock(MutexTypes&... m);
2163
  ```
2164
 
2165
- *Preconditions:* If a `MutexTypes` type is not a recursive mutex, the
2166
- calling thread does not own the corresponding mutex element of `m`.
2167
-
2168
  *Effects:* Initializes `pm` with `tie(m...)`. Then if
2169
  `sizeof...(MutexTypes)` is `0`, no effects. Otherwise if
2170
  `sizeof...(MutexTypes)` is `1`, then `m.lock()`. Otherwise,
2171
  `lock(m...)`.
2172
 
2173
  ``` cpp
2174
  explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
2175
  ```
2176
 
2177
- *Preconditions:* The calling thread owns all the mutexes in `m`.
 
2178
 
2179
  *Effects:* Initializes `pm` with `tie(m...)`.
2180
 
2181
  *Throws:* Nothing.
2182
 
@@ -2187,10 +5180,12 @@ explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
2187
  *Effects:* For all `i` in \[`0`, `sizeof...(MutexTypes)`),
2188
  `get<i>(pm).unlock()`.
2189
 
2190
  #### Class template `unique_lock` <a id="thread.lock.unique">[[thread.lock.unique]]</a>
2191
 
 
 
2192
  ``` cpp
2193
  namespace std {
2194
  template<class Mutex>
2195
  class unique_lock {
2196
  public:
@@ -2236,13 +5231,10 @@ namespace std {
2236
 
2237
  private:
2238
  mutex_type* pm; // exposition only
2239
  bool owns; // exposition only
2240
  };
2241
-
2242
- template<class Mutex>
2243
- void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
2244
  }
2245
  ```
2246
 
2247
  An object of type `unique_lock` controls the ownership of a lockable
2248
  object within a scope. Ownership of the lockable object may be acquired
@@ -2266,19 +5258,16 @@ meets the *Cpp17TimedLockable* requirements. — *end note*]
2266
 
2267
  ``` cpp
2268
  unique_lock() noexcept;
2269
  ```
2270
 
2271
- *Ensures:* `pm == 0` and `owns == false`.
2272
 
2273
  ``` cpp
2274
  explicit unique_lock(mutex_type& m);
2275
  ```
2276
 
2277
- *Preconditions:* If `mutex_type` is not a recursive mutex the calling
2278
- thread does not own the mutex.
2279
-
2280
  *Effects:* Calls `m.lock()`.
2281
 
2282
  *Ensures:* `pm == addressof(m)` and `owns == true`.
2283
 
2284
  ``` cpp
@@ -2290,35 +5279,33 @@ unique_lock(mutex_type& m, defer_lock_t) noexcept;
2290
  ``` cpp
2291
  unique_lock(mutex_type& m, try_to_lock_t);
2292
  ```
2293
 
2294
  *Preconditions:* The supplied `Mutex` type meets the *Cpp17Lockable*
2295
- requirements [[thread.req.lockable.req]]. If `mutex_type` is not a
2296
- recursive mutex the calling thread does not own the mutex.
2297
 
2298
  *Effects:* Calls `m.try_lock()`.
2299
 
2300
  *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
2301
  value returned by the call to `m.try_lock()`.
2302
 
2303
  ``` cpp
2304
  unique_lock(mutex_type& m, adopt_lock_t);
2305
  ```
2306
 
2307
- *Preconditions:* The calling thread owns the mutex.
2308
 
2309
  *Ensures:* `pm == addressof(m)` and `owns == true`.
2310
 
2311
  *Throws:* Nothing.
2312
 
2313
  ``` cpp
2314
  template<class Clock, class Duration>
2315
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
2316
  ```
2317
 
2318
- *Preconditions:* If `mutex_type` is not a recursive mutex the calling
2319
- thread does not own the mutex. The supplied `Mutex` type meets the
2320
  *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
2321
 
2322
  *Effects:* Calls `m.try_lock_until(abs_time)`.
2323
 
2324
  *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
@@ -2327,12 +5314,11 @@ value returned by the call to `m.try_lock_until(abs_time)`.
2327
  ``` cpp
2328
  template<class Rep, class Period>
2329
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
2330
  ```
2331
 
2332
- *Preconditions:* If `mutex_type` is not a recursive mutex the calling
2333
- thread does not own the mutex. The supplied `Mutex` type meets the
2334
  *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
2335
 
2336
  *Effects:* Calls `m.try_lock_for(rel_time)`.
2337
 
2338
  *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
@@ -2393,14 +5379,14 @@ bool try_lock();
2393
  *Preconditions:* The supplied `Mutex` meets the *Cpp17Lockable*
2394
  requirements [[thread.req.lockable.req]].
2395
 
2396
  *Effects:* As if by `pm->try_lock()`.
2397
 
2398
- *Returns:* The value returned by the call to `try_lock()`.
 
2399
 
2400
- *Ensures:* `owns == res`, where `res` is the value returned by the call
2401
- to `try_lock()`.
2402
 
2403
  *Throws:* Any exception thrown by `pm->try_lock()`. `system_error` when
2404
  an exception is required [[thread.req.exception]].
2405
 
2406
  *Error conditions:*
@@ -2416,17 +5402,17 @@ template<class Clock, class Duration>
2416
  *Preconditions:* The supplied `Mutex` type meets the
2417
  *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
2418
 
2419
  *Effects:* As if by `pm->try_lock_until(abs_time)`.
2420
 
2421
- *Returns:* The value returned by the call to `try_lock_until(abs_time)`.
 
2422
 
2423
- *Ensures:* `owns == res`, where `res` is the value returned by the call
2424
- to `try_lock_until(abs_time)`.
2425
 
2426
- *Throws:* Any exception thrown by `pm->try_lock_until()`. `system_error`
2427
- when an exception is required [[thread.req.exception]].
2428
 
2429
  *Error conditions:*
2430
 
2431
  - `operation_not_permitted` — if `pm` is `nullptr`.
2432
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
@@ -2439,17 +5425,17 @@ template<class Rep, class Period>
2439
  *Preconditions:* The supplied `Mutex` type meets the
2440
  *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
2441
 
2442
  *Effects:* As if by `pm->try_lock_for(rel_time)`.
2443
 
2444
- *Returns:* The value returned by the call to `try_lock_for(rel_time)`.
 
2445
 
2446
- *Ensures:* `owns == res`, where `res` is the value returned by the call
2447
- to `try_lock_for(rel_time)`.
2448
 
2449
- *Throws:* Any exception thrown by `pm->try_lock_for()`. `system_error`
2450
- when an exception is required [[thread.req.exception]].
2451
 
2452
  *Error conditions:*
2453
 
2454
  - `operation_not_permitted` — if `pm` is `nullptr`.
2455
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
@@ -2479,14 +5465,14 @@ void swap(unique_lock& u) noexcept;
2479
 
2480
  ``` cpp
2481
  mutex_type* release() noexcept;
2482
  ```
2483
 
2484
- *Returns:* The previous value of `pm`.
2485
-
2486
  *Ensures:* `pm == 0` and `owns == false`.
2487
 
 
 
2488
  ``` cpp
2489
  template<class Mutex>
2490
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
2491
  ```
2492
 
@@ -2512,10 +5498,12 @@ mutex_type *mutex() const noexcept;
2512
 
2513
  *Returns:* `pm`.
2514
 
2515
  #### Class template `shared_lock` <a id="thread.lock.shared">[[thread.lock.shared]]</a>
2516
 
 
 
2517
  ``` cpp
2518
  namespace std {
2519
  template<class Mutex>
2520
  class shared_lock {
2521
  public:
@@ -2559,13 +5547,10 @@ namespace std {
2559
 
2560
  private:
2561
  mutex_type* pm; // exposition only
2562
  bool owns; // exposition only
2563
  };
2564
-
2565
- template<class Mutex>
2566
- void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
2567
  }
2568
  ```
2569
 
2570
  An object of type `shared_lock` controls the shared ownership of a
2571
  lockable object within a scope. Shared ownership of the lockable object
@@ -2573,15 +5558,19 @@ may be acquired at construction or after construction, and may be
2573
  transferred, after acquisition, to another `shared_lock` object. Objects
2574
  of type `shared_lock` are not copyable but are movable. The behavior of
2575
  a program is undefined if the contained pointer `pm` is not null and the
2576
  lockable object pointed to by `pm` does not exist for the entire
2577
  remaining lifetime [[basic.life]] of the `shared_lock` object. The
2578
- supplied `Mutex` type shall meet the shared mutex requirements
2579
- [[thread.sharedtimedmutex.requirements]].
2580
 
2581
- [*Note 1*: `shared_lock<Mutex>` meets the *Cpp17TimedLockable*
2582
- requirements [[thread.req.lockable.timed]]. *end note*]
 
 
 
 
2583
 
2584
  ##### Constructors, destructor, and assignment <a id="thread.lock.shared.cons">[[thread.lock.shared.cons]]</a>
2585
 
2586
  ``` cpp
2587
  shared_lock() noexcept;
@@ -2591,13 +5580,10 @@ shared_lock() noexcept;
2591
 
2592
  ``` cpp
2593
  explicit shared_lock(mutex_type& m);
2594
  ```
2595
 
2596
- *Preconditions:* The calling thread does not own the mutex for any
2597
- ownership mode.
2598
-
2599
  *Effects:* Calls `m.lock_shared()`.
2600
 
2601
  *Ensures:* `pm == addressof(m)` and `owns == true`.
2602
 
2603
  ``` cpp
@@ -2608,34 +5594,31 @@ shared_lock(mutex_type& m, defer_lock_t) noexcept;
2608
 
2609
  ``` cpp
2610
  shared_lock(mutex_type& m, try_to_lock_t);
2611
  ```
2612
 
2613
- *Preconditions:* The calling thread does not own the mutex for any
2614
- ownership mode.
2615
-
2616
  *Effects:* Calls `m.try_lock_shared()`.
2617
 
2618
  *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
2619
  value returned by the call to `m.try_lock_shared()`.
2620
 
2621
  ``` cpp
2622
  shared_lock(mutex_type& m, adopt_lock_t);
2623
  ```
2624
 
2625
- *Preconditions:* The calling thread has shared ownership of the mutex.
2626
 
2627
  *Ensures:* `pm == addressof(m)` and `owns == true`.
2628
 
2629
  ``` cpp
2630
  template<class Clock, class Duration>
2631
  shared_lock(mutex_type& m,
2632
  const chrono::time_point<Clock, Duration>& abs_time);
2633
  ```
2634
 
2635
- *Preconditions:* The calling thread does not own the mutex for any
2636
- ownership mode.
2637
 
2638
  *Effects:* Calls `m.try_lock_shared_until(abs_time)`.
2639
 
2640
  *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
2641
  value returned by the call to `m.try_lock_shared_until(abs_time)`.
@@ -2644,12 +5627,12 @@ value returned by the call to `m.try_lock_shared_until(abs_time)`.
2644
  template<class Rep, class Period>
2645
  shared_lock(mutex_type& m,
2646
  const chrono::duration<Rep, Period>& rel_time);
2647
  ```
2648
 
2649
- *Preconditions:* The calling thread does not own the mutex for any
2650
- ownership mode.
2651
 
2652
  *Effects:* Calls `m.try_lock_shared_for(rel_time)`.
2653
 
2654
  *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
2655
  value returned by the call to `m.try_lock_shared_for(rel_time)`.
@@ -2700,15 +5683,15 @@ when an exception is required [[thread.req.exception]].
2700
  bool try_lock();
2701
  ```
2702
 
2703
  *Effects:* As if by `pm->try_lock_shared()`.
2704
 
2705
- *Returns:* The value returned by the call to `pm->try_lock_shared()`.
2706
-
2707
  *Ensures:* `owns == res`, where `res` is the value returned by the call
2708
  to `pm->try_lock_shared()`.
2709
 
 
 
2710
  *Throws:* Any exception thrown by `pm->try_lock_shared()`.
2711
  `system_error` when an exception is required [[thread.req.exception]].
2712
 
2713
  *Error conditions:*
2714
 
@@ -2718,18 +5701,21 @@ to `pm->try_lock_shared()`.
2718
  ``` cpp
2719
  template<class Clock, class Duration>
2720
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
2721
  ```
2722
 
 
 
 
2723
  *Effects:* As if by `pm->try_lock_shared_until(abs_time)`.
2724
 
2725
- *Returns:* The value returned by the call to
2726
- `pm->try_lock_shared_until(abs_time)`.
2727
-
2728
  *Ensures:* `owns == res`, where `res` is the value returned by the call
2729
  to `pm->try_lock_shared_until(abs_time)`.
2730
 
 
 
 
2731
  *Throws:* Any exception thrown by `pm->try_lock_shared_until(abs_time)`.
2732
  `system_error` when an exception is required [[thread.req.exception]].
2733
 
2734
  *Error conditions:*
2735
 
@@ -2739,18 +5725,21 @@ to `pm->try_lock_shared_until(abs_time)`.
2739
  ``` cpp
2740
  template<class Rep, class Period>
2741
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
2742
  ```
2743
 
 
 
 
2744
  *Effects:* As if by `pm->try_lock_shared_for(rel_time)`.
2745
 
2746
- *Returns:* The value returned by the call to
2747
- `pm->try_lock_shared_for(rel_time)`.
2748
-
2749
  *Ensures:* `owns == res`, where `res` is the value returned by the call
2750
  to `pm->try_lock_shared_for(rel_time)`.
2751
 
 
 
 
2752
  *Throws:* Any exception thrown by `pm->try_lock_shared_for(rel_time)`.
2753
  `system_error` when an exception is required [[thread.req.exception]].
2754
 
2755
  *Error conditions:*
2756
 
@@ -2782,14 +5771,14 @@ void swap(shared_lock& sl) noexcept;
2782
 
2783
  ``` cpp
2784
  mutex_type* release() noexcept;
2785
  ```
2786
 
2787
- *Returns:* The previous value of `pm`.
2788
-
2789
  *Ensures:* `pm == nullptr` and `owns == false`.
2790
 
 
 
2791
  ``` cpp
2792
  template<class Mutex>
2793
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
2794
  ```
2795
 
@@ -2849,11 +5838,11 @@ when suitably instantiated. — *end note*]
2849
 
2850
  *Effects:* All arguments are locked via a sequence of calls to `lock()`,
2851
  `try_lock()`, or `unlock()` on each argument. The sequence of calls does
2852
  not result in deadlock, but is otherwise unspecified.
2853
 
2854
- [*Note 3*: A deadlock avoidance algorithm such as try-and-back-off must
2855
  be used, but the specific algorithm is not specified to avoid
2856
  over-constraining implementations. — *end note*]
2857
 
2858
  If a call to `lock()` or `try_lock()` throws an exception, `unlock()` is
2859
  called for any argument that had been locked by a call to `lock()` or
@@ -2898,18 +5887,18 @@ template<class Callable, class... Args>
2898
  *Mandates:* `is_invocable_v<Callable, Args...>` is `true`.
2899
 
2900
  *Effects:* An execution of `call_once` that does not call its `func` is
2901
  a *passive* execution. An execution of `call_once` that calls its `func`
2902
  is an *active* execution. An active execution calls *INVOKE*(
2903
- std::forward\<Callable\>(func), std::forward\<Args\>(args)...). If such
2904
- a call to `func` throws an exception the execution is *exceptional*,
2905
- otherwise it is *returning*. An exceptional execution propagates the
2906
- exception to the caller of `call_once`. Among all executions of
2907
- `call_once` for any given `once_flag`: at most one is a returning
2908
- execution; if there is a returning execution, it is the last active
2909
- execution; and there are passive executions only if there is a returning
2910
- execution.
2911
 
2912
  [*Note 1*: Passive executions allow other threads to reliably observe
2913
  the results produced by the earlier returning execution. — *end note*]
2914
 
2915
  *Synchronization:* For any given `once_flag`: all active executions
@@ -2953,10 +5942,12 @@ public:
2953
 
2954
  — *end example*]
2955
 
2956
  ## Condition variables <a id="thread.condition">[[thread.condition]]</a>
2957
 
 
 
2958
  Condition variables provide synchronization primitives used to block a
2959
  thread until notified by some other thread that some condition is met or
2960
  until a system time is reached. Class `condition_variable` provides a
2961
  condition variable that can only wait on an object of type
2962
  `unique_lock<mutex>`, allowing the implementation to be more efficient.
@@ -2976,22 +5967,25 @@ three atomic parts:
2976
  3. the reacquisition of the lock.
2977
 
2978
  The implementation behaves as if all executions of `notify_one`,
2979
  `notify_all`, and each part of the `wait`, `wait_for`, and `wait_until`
2980
  executions are executed in a single unspecified total order consistent
2981
- with the "happens before" order.
2982
 
2983
  Condition variable construction and destruction need not be
2984
  synchronized.
2985
 
2986
  ### Header `<condition_variable>` synopsis <a id="condition.variable.syn">[[condition.variable.syn]]</a>
2987
 
2988
  ``` cpp
2989
  namespace std {
 
2990
  class condition_variable;
 
2991
  class condition_variable_any;
2992
 
 
2993
  void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
2994
 
2995
  enum class cv_status { no_timeout, timeout };
2996
  }
2997
  ```
@@ -3022,16 +6016,12 @@ cond.notify_all();
3022
 
3023
  *Synchronization:* The implied `lk.unlock()` call is sequenced after the
3024
  destruction of all objects with thread storage duration associated with
3025
  the current thread.
3026
 
3027
- [*Note 1*: The supplied lock will be held until the thread exits, and
3028
- care should be taken to ensure that this does not cause deadlock due to
3029
- lock ordering issues. After calling `notify_all_at_thread_exit` it is
3030
- recommended that the thread should be exited as soon as possible, and
3031
- that no blocking or time-consuming tasks are run on that
3032
- thread. — *end note*]
3033
 
3034
  [*Note 2*: It is the user’s responsibility to ensure that waiting
3035
  threads do not erroneously assume that the thread has finished if they
3036
  experience spurious wakeups. This typically requires that the condition
3037
  being waited for is satisfied while holding the lock on `lk`, and that
@@ -3095,18 +6085,18 @@ required [[thread.req.exception]].
3095
  ~condition_variable();
3096
  ```
3097
 
3098
  *Preconditions:* There is no thread blocked on `*this`.
3099
 
3100
- [*Note 1*: That is, all threads have been notified; they could
3101
  subsequently block on the lock specified in the wait. This relaxes the
3102
  usual rules, which would have required all wait calls to happen before
3103
  destruction. Only the notification to unblock the wait needs to happen
3104
- before destruction. The user should take care to ensure that no threads
3105
- wait on `*this` once the destructor has been started, especially when
3106
- the waiting threads are calling the wait functions in a loop or using
3107
- the overloads of `wait`, `wait_for`, or `wait_until` that take a
3108
  predicate. — *end note*]
3109
 
3110
  ``` cpp
3111
  void notify_one() noexcept;
3112
  ```
@@ -3138,21 +6128,21 @@ locked by the calling thread, and either
3138
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
3139
  then returns.
3140
  - The function will unblock when signaled by a call to `notify_one()` or
3141
  a call to `notify_all()`, or spuriously.
3142
 
3143
- *Remarks:* If the function fails to meet the postcondition,
3144
- `terminate()` is called [[except.terminate]].
3145
-
3146
- [*Note 2*: This can happen if the re-locking of the mutex throws an
3147
- exception. — *end note*]
3148
-
3149
  *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3150
  the calling thread.
3151
 
3152
  *Throws:* Nothing.
3153
 
 
 
 
 
 
 
3154
  ``` cpp
3155
  template<class Predicate>
3156
  void wait(unique_lock<mutex>& lock, Predicate pred);
3157
  ```
3158
 
@@ -3169,21 +6159,21 @@ locked by the calling thread, and either
3169
  ``` cpp
3170
  while (!pred())
3171
  wait(lock);
3172
  ```
3173
 
3174
- *Remarks:* If the function fails to meet the postcondition,
3175
- `terminate()` is called [[except.terminate]].
3176
-
3177
- [*Note 3*: This can happen if the re-locking of the mutex throws an
3178
- exception. — *end note*]
3179
-
3180
  *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3181
  the calling thread.
3182
 
3183
  *Throws:* Any exception thrown by `pred`.
3184
 
 
 
 
 
 
 
3185
  ``` cpp
3186
  template<class Clock, class Duration>
3187
  cv_status wait_until(unique_lock<mutex>& lock,
3188
  const chrono::time_point<Clock, Duration>& abs_time);
3189
  ```
@@ -3205,25 +6195,25 @@ locked by the calling thread, and either
3205
  call to `notify_all()`, expiration of the absolute
3206
  timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
3207
  - If the function exits via an exception, `lock.lock()` is called prior
3208
  to exiting the function.
3209
 
 
 
 
 
 
 
 
 
 
3210
  *Remarks:* If the function fails to meet the postcondition,
3211
- `terminate()` is called [[except.terminate]].
3212
 
3213
  [*Note 4*: This can happen if the re-locking of the mutex throws an
3214
  exception. — *end note*]
3215
 
3216
- *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3217
- the calling thread.
3218
-
3219
- *Returns:* `cv_status::timeout` if the absolute
3220
- timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
3221
- `cv_status::no_timeout`.
3222
-
3223
- *Throws:* Timeout-related exceptions [[thread.req.timing]].
3224
-
3225
  ``` cpp
3226
  template<class Rep, class Period>
3227
  cv_status wait_for(unique_lock<mutex>& lock,
3228
  const chrono::duration<Rep, Period>& rel_time);
3229
  ```
@@ -3240,25 +6230,25 @@ locked by the calling thread, and either
3240
 
3241
  ``` cpp
3242
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
3243
  ```
3244
 
 
 
 
3245
  *Returns:* `cv_status::timeout` if the relative
3246
  timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
3247
  `cv_status::no_timeout`.
3248
 
3249
- *Remarks:* If the function fails to meet the postcondition,
3250
- `terminate()` is called [[except.terminate]].
 
 
3251
 
3252
  [*Note 5*: This can happen if the re-locking of the mutex throws an
3253
  exception. — *end note*]
3254
 
3255
- *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3256
- the calling thread.
3257
-
3258
- *Throws:* Timeout-related exceptions [[thread.req.timing]].
3259
-
3260
  ``` cpp
3261
  template<class Clock, class Duration, class Predicate>
3262
  bool wait_until(unique_lock<mutex>& lock,
3263
  const chrono::time_point<Clock, Duration>& abs_time,
3264
  Predicate pred);
@@ -3279,26 +6269,26 @@ while (!pred())
3279
  if (wait_until(lock, abs_time) == cv_status::timeout)
3280
  return pred();
3281
  return true;
3282
  ```
3283
 
3284
- *Remarks:* If the function fails to meet the postcondition,
3285
- `terminate()` is called [[except.terminate]].
3286
-
3287
- [*Note 6*: This can happen if the re-locking of the mutex throws an
3288
- exception. — *end note*]
3289
-
3290
  *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3291
  the calling thread.
3292
 
3293
- [*Note 7*: The returned value indicates whether the predicate evaluated
3294
  to `true` regardless of whether the timeout was
3295
  triggered. — *end note*]
3296
 
3297
  *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
3298
  exception thrown by `pred`.
3299
 
 
 
 
 
 
 
3300
  ``` cpp
3301
  template<class Rep, class Period, class Predicate>
3302
  bool wait_for(unique_lock<mutex>& lock,
3303
  const chrono::duration<Rep, Period>& rel_time,
3304
  Predicate pred);
@@ -3319,37 +6309,40 @@ return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred))
3319
  ```
3320
 
3321
  [*Note 8*: There is no blocking if `pred()` is initially `true`, even
3322
  if the timeout has already expired. — *end note*]
3323
 
3324
- *Remarks:* If the function fails to meet the postcondition,
3325
- `terminate()` is called [[except.terminate]].
3326
-
3327
- [*Note 9*: This can happen if the re-locking of the mutex throws an
3328
- exception. — *end note*]
3329
-
3330
  *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
3331
  the calling thread.
3332
 
3333
- [*Note 10*: The returned value indicates whether the predicate
3334
- evaluates to `true` regardless of whether the timeout was
3335
  triggered. — *end note*]
3336
 
3337
  *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
3338
  exception thrown by `pred`.
3339
 
 
 
 
 
 
 
3340
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
3341
 
3342
- A `Lock` type shall meet the *Cpp17BasicLockable* requirements
3343
- [[thread.req.lockable.basic]].
 
 
 
3344
 
3345
  [*Note 1*: All of the standard mutex types meet this requirement. If a
3346
- `Lock` type other than one of the standard mutex types or a
3347
- `unique_lock` wrapper for a standard mutex type is used with
3348
- `condition_variable_any`, the user should ensure that any necessary
3349
- synchronization is in place with respect to the predicate associated
3350
- with the `condition_variable_any` instance. — *end note*]
3351
 
3352
  ``` cpp
3353
  namespace std {
3354
  class condition_variable_any {
3355
  public:
@@ -3409,18 +6402,18 @@ required [[thread.req.exception]].
3409
  ~condition_variable_any();
3410
  ```
3411
 
3412
  *Preconditions:* There is no thread blocked on `*this`.
3413
 
3414
- [*Note 1*: That is, all threads have been notified; they could
3415
  subsequently block on the lock specified in the wait. This relaxes the
3416
  usual rules, which would have required all wait calls to happen before
3417
  destruction. Only the notification to unblock the wait needs to happen
3418
- before destruction. The user should take care to ensure that no threads
3419
- wait on `*this` once the destructor has been started, especially when
3420
- the waiting threads are calling the wait functions in a loop or using
3421
- the overloads of `wait`, `wait_for`, or `wait_until` that take a
3422
  predicate. — *end note*]
3423
 
3424
  ``` cpp
3425
  void notify_one() noexcept;
3426
  ```
@@ -3447,20 +6440,20 @@ template<class Lock>
3447
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
3448
  and returns.
3449
  - The function will unblock when signaled by a call to `notify_one()`, a
3450
  call to `notify_all()`, or spuriously.
3451
 
 
 
 
 
3452
  *Remarks:* If the function fails to meet the postcondition,
3453
- `terminate()` is called [[except.terminate]].
3454
 
3455
  [*Note 1*: This can happen if the re-locking of the mutex throws an
3456
  exception. — *end note*]
3457
 
3458
- *Ensures:* `lock` is locked by the calling thread.
3459
-
3460
- *Throws:* Nothing.
3461
-
3462
  ``` cpp
3463
  template<class Lock, class Predicate>
3464
  void wait(Lock& lock, Predicate pred);
3465
  ```
3466
 
@@ -3485,24 +6478,24 @@ template<class Lock, class Clock, class Duration>
3485
  call to `notify_all()`, expiration of the absolute
3486
  timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
3487
  - If the function exits via an exception, `lock.lock()` is called prior
3488
  to exiting the function.
3489
 
3490
- *Remarks:* If the function fails to meet the postcondition,
3491
- `terminate()` is called [[except.terminate]].
3492
-
3493
- [*Note 2*: This can happen if the re-locking of the mutex throws an
3494
- exception. — *end note*]
3495
-
3496
  *Ensures:* `lock` is locked by the calling thread.
3497
 
3498
  *Returns:* `cv_status::timeout` if the absolute
3499
  timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
3500
  `cv_status::no_timeout`.
3501
 
3502
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
3503
 
 
 
 
 
 
 
3504
  ``` cpp
3505
  template<class Lock, class Rep, class Period>
3506
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
3507
  ```
3508
 
@@ -3510,24 +6503,24 @@ template<class Lock, class Rep, class Period>
3510
 
3511
  ``` cpp
3512
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
3513
  ```
3514
 
 
 
3515
  *Returns:* `cv_status::timeout` if the relative
3516
  timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
3517
  `cv_status::no_timeout`.
3518
 
3519
- *Remarks:* If the function fails to meet the postcondition,
3520
- `terminate()` is called [[except.terminate]].
 
 
3521
 
3522
  [*Note 3*: This can happen if the re-locking of the mutex throws an
3523
  exception. — *end note*]
3524
 
3525
- *Ensures:* `lock` is locked by the calling thread.
3526
-
3527
- *Throws:* Timeout-related exceptions [[thread.req.timing]].
3528
-
3529
  ``` cpp
3530
  template<class Lock, class Clock, class Duration, class Predicate>
3531
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
3532
  ```
3533
 
@@ -3585,18 +6578,18 @@ return pred();
3585
  [*Note 1*: The returned value indicates whether the predicate evaluated
3586
  to `true` regardless of whether there was a stop request. — *end note*]
3587
 
3588
  *Ensures:* `lock` is locked by the calling thread.
3589
 
 
 
3590
  *Remarks:* If the function fails to meet the postcondition, `terminate`
3591
  is called [[except.terminate]].
3592
 
3593
  [*Note 2*: This can happen if the re-locking of the mutex throws an
3594
  exception. — *end note*]
3595
 
3596
- *Throws:* Any exception thrown by `pred`.
3597
-
3598
  ``` cpp
3599
  template<class Lock, class Clock, class Duration, class Predicate>
3600
  bool wait_until(Lock& lock, stop_token stoken,
3601
  const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
3602
  ```
@@ -3607,11 +6600,11 @@ equivalent to:
3607
 
3608
  ``` cpp
3609
  while (!stoken.stop_requested()) {
3610
  if (pred())
3611
  return true;
3612
- if (cv.wait_until(lock, abs_time) == cv_status::timeout)
3613
  return pred();
3614
  }
3615
  return pred();
3616
  ```
3617
 
@@ -3623,19 +6616,19 @@ expired. — *end note*]
3623
  to `true` regardless of whether the timeout was triggered or a stop
3624
  request was made. — *end note*]
3625
 
3626
  *Ensures:* `lock` is locked by the calling thread.
3627
 
3628
- *Remarks:* If the function fails to meet the postcondition, `terminate`
3629
- is called [[except.terminate]].
3630
-
3631
- [*Note 5*: This can happen if the re-locking of the mutex throws an
3632
- exception. — *end note*]
3633
-
3634
  *Throws:* Timeout-related exceptions [[thread.req.timing]], or any
3635
  exception thrown by `pred`.
3636
 
 
 
 
 
 
 
3637
  ``` cpp
3638
  template<class Lock, class Rep, class Period, class Predicate>
3639
  bool wait_for(Lock& lock, stop_token stoken,
3640
  const chrono::duration<Rep, Period>& rel_time, Predicate pred);
3641
  ```
@@ -3647,10 +6640,12 @@ return wait_until(lock, std::move(stoken), chrono::steady_clock::now() + rel_tim
3647
  std::move(pred));
3648
  ```
3649
 
3650
  ## Semaphore <a id="thread.sema">[[thread.sema]]</a>
3651
 
 
 
3652
  Semaphores are lightweight synchronization primitives used to constrain
3653
  concurrent access to a shared resource. They are widely used to
3654
  implement other synchronization primitives and, whenever both are
3655
  applicable, can be more efficient than condition variables.
3656
 
@@ -3661,10 +6656,11 @@ implementation of a counting semaphore with a unit resource count.
3661
 
3662
  ### Header `<semaphore>` synopsis <a id="semaphore.syn">[[semaphore.syn]]</a>
3663
 
3664
  ``` cpp
3665
  namespace std {
 
3666
  template<ptrdiff_t least_max_value = implementation-defined>
3667
  class counting_semaphore;
3668
 
3669
  using binary_semaphore = counting_semaphore<1>;
3670
  }
@@ -3672,11 +6668,11 @@ namespace std {
3672
 
3673
  ### Class template `counting_semaphore` <a id="thread.sema.cnt">[[thread.sema.cnt]]</a>
3674
 
3675
  ``` cpp
3676
  namespace std {
3677
- template<ptrdiff_t least_max_value = implementation-defined>
3678
  class counting_semaphore {
3679
  public:
3680
  static constexpr ptrdiff_t max() noexcept;
3681
 
3682
  constexpr explicit counting_semaphore(ptrdiff_t desired);
@@ -3771,11 +6767,11 @@ return `false` in the absence of contending semaphore operations.
3771
  void acquire();
3772
  ```
3773
 
3774
  *Effects:* Repeatedly performs the following steps, in order:
3775
 
3776
- - Evaluates `try_acquire`. If the result is `true`, returns.
3777
  - Blocks on `*this` until `counter` is greater than zero.
3778
 
3779
  *Throws:* `system_error` when an exception is
3780
  required [[thread.req.exception]].
3781
 
@@ -3807,17 +6803,21 @@ required [[thread.req.exception]].
3807
  *Error conditions:* Any of the error conditions allowed for mutex
3808
  types [[thread.mutex.requirements.mutex]].
3809
 
3810
  ## Coordination types <a id="thread.coord">[[thread.coord]]</a>
3811
 
3812
- This subclause describes various concepts related to thread
 
 
3813
  coordination, and defines the coordination types `latch` and `barrier`.
3814
  These types facilitate concurrent computation performed by a number of
3815
  threads.
3816
 
3817
  ### Latches <a id="thread.latch">[[thread.latch]]</a>
3818
 
 
 
3819
  A latch is a thread coordination mechanism that allows any number of
3820
  threads to block until an expected number of threads arrive at the latch
3821
  (via the `count_down` function). The expected count is set when the
3822
  latch is created. An individual latch is a single-use object; once the
3823
  expected count has been reached, the latch cannot be reused.
@@ -3930,10 +6930,12 @@ count_down(update);
3930
  wait();
3931
  ```
3932
 
3933
  ### Barriers <a id="thread.barrier">[[thread.barrier]]</a>
3934
 
 
 
3935
  A barrier is a thread coordination mechanism whose lifetime consists of
3936
  a sequence of barrier phases, where each phase allows at most an
3937
  expected number of threads to block until the expected number of threads
3938
  arrive at the barrier.
3939
 
@@ -3981,17 +6983,14 @@ namespace std {
3981
 
3982
  Each *barrier phase* consists of the following steps:
3983
 
3984
  - The expected count is decremented by each call to `arrive` or
3985
  `arrive_and_drop`.
3986
- - When the expected count reaches zero, the phase completion step is
3987
- run. For the specialization with the default value of the
3988
- `CompletionFunction` template parameter, the completion step is run as
3989
- part of the call to `arrive` or `arrive_and_drop` that caused the
3990
- expected count to reach zero. For other specializations, the
3991
- completion step is run on one of the threads that arrived at the
3992
- barrier during the phase.
3993
  - When the completion step finishes, the expected count is reset to what
3994
  was specified by the `expected` argument to the constructor, possibly
3995
  adjusted by calls to `arrive_and_drop`, and the next phase starts.
3996
 
3997
  Each phase defines a *phase synchronization point*. Threads that arrive
@@ -4147,61 +7146,68 @@ well. — *end note*]
4147
  ### Header `<future>` synopsis <a id="future.syn">[[future.syn]]</a>
4148
 
4149
  ``` cpp
4150
  namespace std {
4151
  enum class future_errc {
4152
- broken_promise = implementation-defined,
4153
- future_already_retrieved = implementation-defined,
4154
- promise_already_satisfied = implementation-defined,
4155
- no_state = implementation-defined
4156
  };
4157
 
4158
  enum class launch : unspecified{} {
4159
  async = unspecified{},
4160
  deferred = unspecified{},
4161
- implementation-defined
4162
  };
4163
 
4164
  enum class future_status {
4165
  ready,
4166
  timeout,
4167
  deferred
4168
  };
4169
 
 
4170
  template<> struct is_error_code_enum<future_errc> : public true_type { };
4171
  error_code make_error_code(future_errc e) noexcept;
4172
  error_condition make_error_condition(future_errc e) noexcept;
4173
 
4174
  const error_category& future_category() noexcept;
4175
 
 
4176
  class future_error;
4177
 
 
4178
  template<class R> class promise;
4179
  template<class R> class promise<R&>;
4180
  template<> class promise<void>;
4181
 
4182
  template<class R>
4183
  void swap(promise<R>& x, promise<R>& y) noexcept;
4184
 
4185
  template<class R, class Alloc>
4186
  struct uses_allocator<promise<R>, Alloc>;
4187
 
 
4188
  template<class R> class future;
4189
  template<class R> class future<R&>;
4190
  template<> class future<void>;
4191
 
 
4192
  template<class R> class shared_future;
4193
  template<class R> class shared_future<R&>;
4194
  template<> class shared_future<void>;
4195
 
 
4196
  template<class> class packaged_task; // not defined
4197
  template<class R, class... ArgTypes>
4198
  class packaged_task<R(ArgTypes...)>;
4199
 
4200
  template<class R, class... ArgTypes>
4201
  void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept;
4202
 
 
4203
  template<class F, class... Args>
4204
  [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
4205
  async(F&& f, Args&&... args);
4206
  template<class F, class... Args>
4207
  [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
@@ -4227,13 +7233,14 @@ const error_category& future_category() noexcept;
4227
  ```
4228
 
4229
  *Returns:* A reference to an object of a type derived from class
4230
  `error_category`.
4231
 
4232
- The object’s `default_error_condition` and equivalent virtual functions
4233
- shall behave as specified for the class `error_category`. The object’s
4234
- `name` virtual function returns a pointer to the string `"future"`.
 
4235
 
4236
  ``` cpp
4237
  error_code make_error_code(future_errc e) noexcept;
4238
  ```
4239
 
@@ -4285,11 +7292,11 @@ const char* what() const noexcept;
4285
  Many of the classes introduced in subclause  [[futures]] use some state
4286
  to communicate results. This *shared state* consists of some state
4287
  information and some (possibly not yet evaluated) *result*, which can be
4288
  a (possibly void) value or an exception.
4289
 
4290
- [*Note 1*: Futures, promises, and tasks defined in this clause
4291
  reference such shared state. — *end note*]
4292
 
4293
  [*Note 2*: The result can be any kind of object including a function to
4294
  compute that result, as used by `async` when `policy` is
4295
  `launch::deferred`. — *end note*]
@@ -4395,18 +7402,18 @@ namespace std {
4395
  // setting the result with deferred notification
4396
  void set_value_at_thread_exit(see below);
4397
  void set_exception_at_thread_exit(exception_ptr p);
4398
  };
4399
 
4400
- template<class R>
4401
- void swap(promise<R>& x, promise<R>& y) noexcept;
4402
-
4403
  template<class R, class Alloc>
4404
  struct uses_allocator<promise<R>, Alloc>;
4405
  }
4406
  ```
4407
 
 
 
 
4408
  The implementation provides the template `promise` and two
4409
  specializations, `promise<R&>` and `promise<{}void>`. These differ only
4410
  in the argument type of the member functions `set_value` and
4411
  `set_value_at_thread_exit`, as set out in their descriptions, below.
4412
 
@@ -4419,12 +7426,12 @@ the promise object.
4419
  template<class R, class Alloc>
4420
  struct uses_allocator<promise<R>, Alloc>
4421
  : true_type { };
4422
  ```
4423
 
4424
- *Preconditions:* `Alloc` meets the *Cpp17Allocator* requirements
4425
- ([[cpp17.allocator]]).
4426
 
4427
  ``` cpp
4428
  promise();
4429
  template<class Allocator>
4430
  promise(allocator_arg_t, const Allocator& a);
@@ -4469,19 +7476,19 @@ to the call to `swap`. `other` has the shared state (if any) that
4469
 
4470
  ``` cpp
4471
  future<R> get_future();
4472
  ```
4473
 
4474
- *Returns:* A `future<R>` object with the same shared state as `*this`.
4475
-
4476
  *Synchronization:* Calls to this function do not introduce data
4477
  races  [[intro.multithread]] with calls to `set_value`, `set_exception`,
4478
  `set_value_at_thread_exit`, or `set_exception_at_thread_exit`.
4479
 
4480
  [*Note 1*: Such calls need not synchronize with each
4481
  other. — *end note*]
4482
 
 
 
4483
  *Throws:* `future_error` if `*this` has no shared state or if
4484
  `get_future` has already been called on a `promise` with the same shared
4485
  state as `*this`.
4486
 
4487
  *Error conditions:*
@@ -4605,13 +7612,13 @@ move-assignment operator, `share`, or `valid` on a `future` object for
4605
  which `valid() == false` is undefined.
4606
 
4607
  [*Note 2*: It is valid to move from a future object for which
4608
  `valid() == false`. — *end note*]
4609
 
4610
- [*Note 3*: Implementations should detect this case and throw an object
4611
- of type `future_error` with an error condition of
4612
- `future_errc::no_state`. — *end note*]
4613
 
4614
  ``` cpp
4615
  namespace std {
4616
  template<class R>
4617
  class future {
@@ -4637,10 +7644,13 @@ namespace std {
4637
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
4638
  };
4639
  }
4640
  ```
4641
 
 
 
 
4642
  The implementation provides the template `future` and two
4643
  specializations, `future<R&>` and `future<{}void>`. These differ only in
4644
  the return type and return value of the member function `get`, as set
4645
  out in its description, below.
4646
 
@@ -4676,29 +7686,30 @@ state that was originally referred to by `rhs` (if any).
4676
 
4677
  ``` cpp
4678
  future& operator=(future&& rhs) noexcept;
4679
  ```
4680
 
4681
- *Effects:*
 
4682
 
4683
  - Releases any shared state [[futures.state]].
4684
  - move assigns the contents of `rhs` to `*this`.
4685
 
4686
  *Ensures:*
4687
 
4688
  - `valid()` returns the same value as `rhs.valid()` prior to the
4689
  assignment.
4690
- - `rhs.valid() == false`.
4691
 
4692
  ``` cpp
4693
  shared_future<R> share() noexcept;
4694
  ```
4695
 
 
 
4696
  *Returns:* `shared_future<R>(std::move(*this))`.
4697
 
4698
- *Ensures:* `valid() == false`.
4699
-
4700
  ``` cpp
4701
  R future::get();
4702
  R& future<R&>::get();
4703
  void future<void>::get();
4704
  ```
@@ -4711,10 +7722,12 @@ member function `get`. — *end note*]
4711
 
4712
  - `wait()`s until the shared state is ready, then retrieves the value
4713
  stored in the shared state;
4714
  - releases any shared state [[futures.state]].
4715
 
 
 
4716
  *Returns:*
4717
 
4718
  - `future::get()` returns the value `v` stored in the object’s shared
4719
  state as `std::move(v)`.
4720
  - `future<R&>::get()` returns the reference stored as value in the
@@ -4722,12 +7735,10 @@ member function `get`. — *end note*]
4722
  - `future<void>::get()` returns nothing.
4723
 
4724
  *Throws:* The stored exception, if an exception was stored in the shared
4725
  state.
4726
 
4727
- *Ensures:* `valid() == false`.
4728
-
4729
  ``` cpp
4730
  bool valid() const noexcept;
4731
  ```
4732
 
4733
  *Returns:* `true` only if `*this` refers to a shared state.
@@ -4800,13 +7811,13 @@ move-assignment operator, the copy-assignment operator, or `valid()` on
4800
  a `shared_future` object for which `valid() == false` is undefined.
4801
 
4802
  [*Note 2*: It is valid to copy or move from a `shared_future` object
4803
  for which `valid()` is `false`. — *end note*]
4804
 
4805
- [*Note 3*: Implementations should detect this case and throw an object
4806
- of type `future_error` with an error condition of
4807
- `future_errc::no_state`. — *end note*]
4808
 
4809
  ``` cpp
4810
  namespace std {
4811
  template<class R>
4812
  class shared_future {
@@ -4832,10 +7843,13 @@ namespace std {
4832
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
4833
  };
4834
  }
4835
  ```
4836
 
 
 
 
4837
  The implementation provides the template `shared_future` and two
4838
  specializations, `shared_future<R&>` and `shared_future<void>`. These
4839
  differ only in the return type and return value of the member function
4840
  `get`, as set out in its description, below.
4841
 
@@ -4880,29 +7894,31 @@ shared state that was originally referred to by `rhs` (if any).
4880
 
4881
  ``` cpp
4882
  shared_future& operator=(shared_future&& rhs) noexcept;
4883
  ```
4884
 
4885
- *Effects:*
 
4886
 
4887
  - Releases any shared state [[futures.state]];
4888
  - move assigns the contents of `rhs` to `*this`.
4889
 
4890
  *Ensures:*
4891
 
4892
  - `valid()` returns the same value as `rhs.valid()` returned prior to
4893
  the assignment.
4894
- - `rhs.valid() == false`.
4895
 
4896
  ``` cpp
4897
  shared_future& operator=(const shared_future& rhs) noexcept;
4898
  ```
4899
 
4900
- *Effects:*
 
4901
 
4902
  - Releases any shared state [[futures.state]];
4903
- - assigns the contents of `rhs` to `*this`. \[*Note 4*: As a result,
4904
  `*this` refers to the same shared state as `rhs` (if
4905
  any). — *end note*]
4906
 
4907
  *Ensures:* `valid() == rhs.valid()`.
4908
 
@@ -4915,20 +7931,20 @@ void shared_future<void>::get() const;
4915
  [*Note 1*: As described above, the template and its two required
4916
  specializations differ only in the return type and return value of the
4917
  member function `get`. — *end note*]
4918
 
4919
  [*Note 2*: Access to a value object stored in the shared state is
4920
- unsynchronized, so programmers should apply only those operations on `R`
4921
- that do not introduce a data race [[intro.multithread]]. — *end note*]
4922
 
4923
  *Effects:* `wait()`s until the shared state is ready, then retrieves the
4924
  value stored in the shared state.
4925
 
4926
  *Returns:*
4927
 
4928
  - `shared_future::get()` returns a const reference to the value stored
4929
- in the object’s shared state. \[*Note 5*: Access through that
4930
  reference after the shared state has been destroyed produces undefined
4931
  behavior; this can be avoided by not storing the reference in any
4932
  storage with a greater lifetime than the `shared_future` object that
4933
  returned the reference. — *end note*]
4934
  - `shared_future<R&>::get()` returns the reference stored as value in
@@ -5008,82 +8024,64 @@ template<class F, class... Args>
5008
  ```
5009
 
5010
  *Mandates:* The following are all `true`:
5011
 
5012
  - `is_constructible_v<decay_t<F>, F>`,
5013
- - `(is_constructible_v<decay_t<Args>, Args> &&...)`,
5014
- - `is_move_constructible_v<decay_t<F>>`,
5015
- - `(is_move_constructible_v<decay_t<Args>> &&...)`, and
5016
  - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
5017
 
5018
- *Preconditions:* `decay_t<F>` and each type in `decay_t<Args>` meet the
5019
- *Cpp17MoveConstructible* requirements.
5020
-
5021
  *Effects:* The first function behaves the same as a call to the second
5022
  function with a `policy` argument of `launch::async | launch::deferred`
5023
  and the same arguments for `F` and `Args`. The second function creates a
5024
  shared state that is associated with the returned `future` object. The
5025
  further behavior of the second function depends on the `policy` argument
5026
  as follows (if more than one of these conditions applies, the
5027
  implementation may choose any of the corresponding policies):
5028
 
5029
  - If `launch::async` is set in `policy`, calls
5030
- `invoke(`*`decay-copy`*`(std::forward<F>(f)),`
5031
- *decay-copy*(std::forward\<Args\>(args))...) ([[func.require]],
5032
- [[thread.thread.constr]]) as if in a new thread of execution
5033
- represented by a `thread` object with the calls to *`decay-copy`*
5034
- being evaluated in the thread that called `async`. Any return value is
5035
- stored as the result in the shared state. Any exception propagated
5036
- from the execution of
5037
- `invoke(`*`decay-copy`*`(std::forward<F>(f)), `*`decay-copy`*`(std::forward<Args>(args))...)`
5038
  is stored as the exceptional result in the shared state. The `thread`
5039
  object is stored in the shared state and affects the behavior of any
5040
  asynchronous return objects that reference that state.
5041
  - If `launch::deferred` is set in `policy`, stores
5042
- *decay-copy*(std::forward\<F\>(f)) and
5043
- *decay-copy*(std::forward\<Args\>(args))... in the shared state. These
5044
- copies of `f` and `args` constitute a *deferred function*. Invocation
5045
- of the deferred function evaluates
5046
  `invoke(std::move(g), std::move(xyz))` where `g` is the stored value
5047
- of *decay-copy*(std::forward\<F\>(f)) and `xyz` is the stored copy of
5048
- *decay-copy*(std::forward\<Args\>(args)).... Any return value is
5049
- stored as the result in the shared state. Any exception propagated
5050
- from the execution of the deferred function is stored as the
5051
- exceptional result in the shared state. The shared state is not made
5052
- ready until the function has completed. The first call to a non-timed
5053
- waiting function [[futures.state]] on an asynchronous return object
5054
- referring to this shared state invokes the deferred function in the
5055
- thread that called the waiting function. Once evaluation of
5056
  `invoke(std::move(g), std::move(xyz))` begins, the function is no
5057
- longer considered deferred. \[*Note 1*: If this policy is specified
5058
- together with other policies, such as when using a `policy` value of
5059
- `launch::async | launch::deferred`, implementations should defer
5060
- invocation or the selection of the policy when no more concurrency can
5061
- be effectively exploited. — *end note*]
5062
  - If no value is set in the launch policy, or a value is set that is
5063
  neither specified in this document nor by the implementation, the
5064
  behavior is undefined.
5065
 
5066
- *Returns:* An object of type
5067
- `future<invoke_result_t<decay_t<F>, decay_t<Args>...>``>` that refers to
5068
- the shared state created by this call to `async`.
5069
 
5070
- [*Note 1*: If a future obtained from `async` is moved outside the local
5071
- scope, other code that uses the future should be aware that the future’s
5072
- destructor can block for the shared state to become
5073
- ready. — *end note*]
5074
-
5075
- *Synchronization:* Regardless of the provided `policy` argument,
5076
-
5077
- - the invocation of `async` synchronizes with [[intro.multithread]] the
5078
- invocation of `f`. \[*Note 2*: This statement applies even when the
5079
- corresponding `future` object is moved to another
5080
- thread. — *end note*] ; and
5081
- - the completion of the function `f` is sequenced
5082
- before [[intro.multithread]] the shared state is made ready.
5083
- \[*Note 3*: `f` might not be called at all, so its completion might
5084
- never happen. — *end note*]
5085
 
5086
  If the implementation chooses the `launch::async` policy,
5087
 
5088
  - a call to a waiting function on an asynchronous return object that
5089
  shares the shared state created by this `async` call shall block until
@@ -5093,27 +8091,37 @@ If the implementation chooses the `launch::async` policy,
5093
  with [[intro.multithread]] the return from the first function that
5094
  successfully detects the ready status of the shared state or with the
5095
  return from the last function that releases the shared state,
5096
  whichever happens first.
5097
 
 
 
 
 
 
 
 
 
5098
  *Throws:* `system_error` if `policy == launch::async` and the
5099
  implementation is unable to start a new thread, or `std::bad_alloc` if
5100
- memory for the internal data structures could not be allocated.
5101
 
5102
  *Error conditions:*
5103
 
5104
  - `resource_unavailable_try_again` — if `policy == launch::async` and
5105
  the system is unable to start a new thread.
5106
 
5107
- [*Note 4*: Line \#1 might not result in concurrency because the `async`
5108
- call uses the default policy, which may use `launch::deferred`, in which
5109
- case the lambda might not be invoked until the `get()` call; in that
5110
- case, `work1` and `work2` are called on the same thread and there is no
5111
- concurrency. — *end note*]
5112
 
5113
  ### Class template `packaged_task` <a id="futures.task">[[futures.task]]</a>
5114
 
 
 
5115
  The class template `packaged_task` defines a type for wrapping a
5116
  function or callable object so that the return value of the function or
5117
  callable object is stored in a future when it is invoked.
5118
 
5119
  When the `packaged_task` object is invoked, its stored task is invoked
@@ -5154,11 +8162,13 @@ namespace std {
5154
 
5155
  void reset();
5156
  };
5157
 
5158
  template<class R, class... ArgTypes>
5159
- void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
 
 
5160
  }
5161
  ```
5162
 
5163
  #### Member functions <a id="futures.task.members">[[futures.task.members]]</a>
5164
 
@@ -5168,11 +8178,11 @@ packaged_task() noexcept;
5168
 
5169
  *Effects:* The object has no shared state and no stored task.
5170
 
5171
  ``` cpp
5172
  template<class F>
5173
- packaged_task(F&& f);
5174
  ```
5175
 
5176
  *Constraints:* `remove_cvref_t<F>` is not the same type as
5177
  `packaged_task<R(ArgTypes...)>`.
5178
 
@@ -5183,13 +8193,29 @@ template<class F>
5183
 
5184
  *Effects:* Constructs a new `packaged_task` object with a shared state
5185
  and initializes the object’s stored task with `std::forward<F>(f)`.
5186
 
5187
  *Throws:* Any exceptions thrown by the copy or move constructor of `f`,
5188
- or `bad_alloc` if memory for the internal data structures could not be
5189
  allocated.
5190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5191
  ``` cpp
5192
  packaged_task(packaged_task&& rhs) noexcept;
5193
  ```
5194
 
5195
  *Effects:* Transfers ownership of `rhs`’s shared state to `*this`,
@@ -5232,20 +8258,20 @@ bool valid() const noexcept;
5232
 
5233
  ``` cpp
5234
  future<R> get_future();
5235
  ```
5236
 
5237
- *Returns:* A `future` object that shares the same shared state as
5238
- `*this`.
5239
-
5240
  *Synchronization:* Calls to this function do not introduce data
5241
  races  [[intro.multithread]] with calls to `operator()` or
5242
  `make_ready_at_thread_exit`.
5243
 
5244
  [*Note 1*: Such calls need not synchronize with each
5245
  other. — *end note*]
5246
 
 
 
 
5247
  *Throws:* A `future_error` object if an error occurs.
5248
 
5249
  *Error conditions:*
5250
 
5251
  - `future_already_retrieved` if `get_future` has already been called on
@@ -5305,12 +8331,12 @@ task stored in `*this`.
5305
  [*Note 2*: This constructs a new shared state for `*this`. The old
5306
  state is abandoned [[futures.state]]. — *end note*]
5307
 
5308
  *Throws:*
5309
 
5310
- - `bad_alloc` if memory for the new shared state could not be allocated.
5311
- - any exception thrown by the move constructor of the task stored in the
5312
  shared state.
5313
  - `future_error` with an error condition of `no_state` if `*this` has no
5314
  shared state.
5315
 
5316
  #### Globals <a id="futures.task.nonmembers">[[futures.task.nonmembers]]</a>
@@ -5322,139 +8348,209 @@ template<class R, class... ArgTypes>
5322
 
5323
  *Effects:* As if by `x.swap(y)`.
5324
 
5325
  <!-- Link reference definitions -->
5326
  [alg.sorting]: algorithms.md#alg.sorting
5327
- [atomics]: atomics.md#atomics
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5328
  [barrier.syn]: #barrier.syn
 
 
5329
  [basic.life]: basic.md#basic.life
5330
  [basic.stc.thread]: basic.md#basic.stc.thread
5331
  [bitmask.types]: library.md#bitmask.types
 
5332
  [class.prop]: class.md#class.prop
 
 
5333
  [condition.variable.syn]: #condition.variable.syn
5334
- [cpp17.allocator]: #cpp17.allocator
5335
  [cpp17.defaultconstructible]: #cpp17.defaultconstructible
5336
  [cpp17.destructible]: #cpp17.destructible
5337
  [cpp17.moveassignable]: #cpp17.moveassignable
5338
  [cpp17.moveconstructible]: #cpp17.moveconstructible
5339
  [defns.block]: intro.md#defns.block
5340
  [except.terminate]: except.md#except.terminate
 
 
 
5341
  [func.require]: utilities.md#func.require
 
5342
  [future.syn]: #future.syn
5343
  [futures]: #futures
5344
  [futures.async]: #futures.async
5345
  [futures.errors]: #futures.errors
5346
  [futures.future.error]: #futures.future.error
5347
  [futures.overview]: #futures.overview
5348
  [futures.promise]: #futures.promise
5349
  [futures.shared.future]: #futures.shared.future
5350
  [futures.state]: #futures.state
5351
  [futures.task]: #futures.task
 
5352
  [futures.task.members]: #futures.task.members
5353
  [futures.task.nonmembers]: #futures.task.nonmembers
5354
  [futures.unique.future]: #futures.unique.future
5355
  [intro.multithread]: basic.md#intro.multithread
 
5356
  [intro.races]: basic.md#intro.races
5357
  [latch.syn]: #latch.syn
 
5358
  [mutex.syn]: #mutex.syn
5359
  [res.on.data.races]: library.md#res.on.data.races
5360
  [res.on.exception.handling]: library.md#res.on.exception.handling
5361
  [semaphore.syn]: #semaphore.syn
5362
  [shared.mutex.syn]: #shared.mutex.syn
 
5363
  [stopcallback]: #stopcallback
5364
  [stopcallback.cons]: #stopcallback.cons
 
5365
  [stopsource]: #stopsource
5366
  [stopsource.cons]: #stopsource.cons
 
5367
  [stopsource.mem]: #stopsource.mem
5368
  [stopsource.nonmembers]: #stopsource.nonmembers
5369
  [stoptoken]: #stoptoken
5370
  [stoptoken.cons]: #stoptoken.cons
 
5371
  [stoptoken.mem]: #stoptoken.mem
5372
  [stoptoken.nonmembers]: #stoptoken.nonmembers
5373
  [syserr]: diagnostics.md#syserr
5374
  [syserr.syserr]: diagnostics.md#syserr.syserr
 
 
5375
  [thread]: #thread
5376
  [thread.barrier]: #thread.barrier
5377
  [thread.barrier.class]: #thread.barrier.class
 
5378
  [thread.condition]: #thread.condition
5379
  [thread.condition.condvar]: #thread.condition.condvar
5380
  [thread.condition.condvarany]: #thread.condition.condvarany
 
 
5381
  [thread.condition.nonmember]: #thread.condition.nonmember
5382
  [thread.condvarany.intwait]: #thread.condvarany.intwait
5383
  [thread.condvarany.wait]: #thread.condvarany.wait
5384
  [thread.coord]: #thread.coord
 
5385
  [thread.general]: #thread.general
5386
  [thread.jthread.class]: #thread.jthread.class
 
5387
  [thread.jthread.cons]: #thread.jthread.cons
5388
  [thread.jthread.mem]: #thread.jthread.mem
5389
  [thread.jthread.special]: #thread.jthread.special
5390
  [thread.jthread.static]: #thread.jthread.static
5391
  [thread.jthread.stop]: #thread.jthread.stop
5392
  [thread.latch]: #thread.latch
5393
  [thread.latch.class]: #thread.latch.class
 
5394
  [thread.lock]: #thread.lock
5395
  [thread.lock.algorithm]: #thread.lock.algorithm
 
5396
  [thread.lock.guard]: #thread.lock.guard
5397
  [thread.lock.scoped]: #thread.lock.scoped
5398
  [thread.lock.shared]: #thread.lock.shared
5399
  [thread.lock.shared.cons]: #thread.lock.shared.cons
 
5400
  [thread.lock.shared.locking]: #thread.lock.shared.locking
5401
  [thread.lock.shared.mod]: #thread.lock.shared.mod
5402
  [thread.lock.shared.obs]: #thread.lock.shared.obs
5403
  [thread.lock.unique]: #thread.lock.unique
5404
  [thread.lock.unique.cons]: #thread.lock.unique.cons
 
5405
  [thread.lock.unique.locking]: #thread.lock.unique.locking
5406
  [thread.lock.unique.mod]: #thread.lock.unique.mod
5407
  [thread.lock.unique.obs]: #thread.lock.unique.obs
5408
  [thread.mutex]: #thread.mutex
5409
  [thread.mutex.class]: #thread.mutex.class
 
5410
  [thread.mutex.recursive]: #thread.mutex.recursive
5411
  [thread.mutex.requirements]: #thread.mutex.requirements
5412
  [thread.mutex.requirements.general]: #thread.mutex.requirements.general
5413
  [thread.mutex.requirements.mutex]: #thread.mutex.requirements.mutex
 
5414
  [thread.once]: #thread.once
5415
  [thread.once.callonce]: #thread.once.callonce
5416
  [thread.once.onceflag]: #thread.once.onceflag
5417
  [thread.req]: #thread.req
5418
  [thread.req.exception]: #thread.req.exception
5419
  [thread.req.lockable]: #thread.req.lockable
5420
  [thread.req.lockable.basic]: #thread.req.lockable.basic
5421
  [thread.req.lockable.general]: #thread.req.lockable.general
5422
  [thread.req.lockable.req]: #thread.req.lockable.req
 
 
5423
  [thread.req.lockable.timed]: #thread.req.lockable.timed
5424
  [thread.req.native]: #thread.req.native
5425
  [thread.req.paramname]: #thread.req.paramname
5426
  [thread.req.timing]: #thread.req.timing
5427
  [thread.sema]: #thread.sema
5428
  [thread.sema.cnt]: #thread.sema.cnt
 
5429
  [thread.sharedmutex.class]: #thread.sharedmutex.class
5430
  [thread.sharedmutex.requirements]: #thread.sharedmutex.requirements
 
5431
  [thread.sharedtimedmutex.class]: #thread.sharedtimedmutex.class
5432
  [thread.sharedtimedmutex.requirements]: #thread.sharedtimedmutex.requirements
 
5433
  [thread.stoptoken]: #thread.stoptoken
5434
  [thread.stoptoken.intro]: #thread.stoptoken.intro
5435
  [thread.stoptoken.syn]: #thread.stoptoken.syn
5436
  [thread.summary]: #thread.summary
5437
  [thread.syn]: #thread.syn
5438
  [thread.thread.algorithm]: #thread.thread.algorithm
5439
  [thread.thread.assign]: #thread.thread.assign
5440
  [thread.thread.class]: #thread.thread.class
 
5441
  [thread.thread.constr]: #thread.thread.constr
5442
  [thread.thread.destr]: #thread.thread.destr
5443
  [thread.thread.id]: #thread.thread.id
5444
  [thread.thread.member]: #thread.thread.member
5445
  [thread.thread.static]: #thread.thread.static
5446
  [thread.thread.this]: #thread.thread.this
5447
  [thread.threads]: #thread.threads
 
5448
  [thread.timedmutex.class]: #thread.timedmutex.class
5449
  [thread.timedmutex.recursive]: #thread.timedmutex.recursive
5450
  [thread.timedmutex.requirements]: #thread.timedmutex.requirements
 
5451
  [time]: time.md#time
5452
  [time.clock]: time.md#time.clock
5453
  [time.clock.req]: time.md#time.clock.req
5454
  [time.duration]: time.md#time.duration
5455
  [time.point]: time.md#time.point
5456
  [unord.hash]: utilities.md#unord.hash
 
 
 
 
 
5457
 
5458
- [^1]: All implementations for which standard time units are meaningful
5459
- must necessarily have a steady clock within their hardware
5460
- implementation.
 
 
 
1
+ # Concurrency support library <a id="thread">[[thread]]</a>
2
 
3
  ## General <a id="thread.general">[[thread.general]]</a>
4
 
5
  The following subclauses describe components to create and manage
6
  threads [[intro.multithread]], perform mutual exclusion, and communicate
7
  conditions and values between threads, as summarized in
8
  [[thread.summary]].
9
 
10
+ **Table: Concurrency support library summary** <a id="thread.summary">[thread.summary]</a>
11
 
12
  | Subclause | | Header |
13
  | -------------------- | ------------------- | --------------------------- |
14
  | [[thread.req]] | Requirements | |
15
  | [[thread.stoptoken]] | Stop tokens | `<stop_token>` |
16
  | [[thread.threads]] | Threads | `<thread>` |
17
+ | [[atomics]] | Atomic operations | `<atomic>`, `<stdatomic.h>` |
18
  | [[thread.mutex]] | Mutual exclusion | `<mutex>`, `<shared_mutex>` |
19
  | [[thread.condition]] | Condition variables | `<condition_variable>` |
20
  | [[thread.sema]] | Semaphores | `<semaphore>` |
21
  | [[thread.coord]] | Coordination types | `<latch>` `<barrier>` |
22
  | [[futures]] | Futures | `<future>` |
 
25
  ## Requirements <a id="thread.req">[[thread.req]]</a>
26
 
27
  ### Template parameter names <a id="thread.req.paramname">[[thread.req.paramname]]</a>
28
 
29
  Throughout this Clause, the names of template parameters are used to
30
+ express type requirements. `Predicate` is a function object type
31
+ [[function.objects]]. Let `pred` denote an lvalue of type `Predicate`.
32
+ Then the expression `pred()` shall be well-formed and the type
33
+ `decltype(pred())` shall model `boolean-testable`
34
+ [[concept.booleantestable]]. The return value of `pred()`, converted to
35
+ `bool`, yields `true` if the corresponding test condition is satisfied,
36
+ and `false` otherwise. If a template parameter is named `Clock`, the
37
+ corresponding template argument shall be a type `C` that meets the
38
+ *Cpp17Clock* requirements [[time.clock.req]]; the program is ill-formed
39
+ if `is_clock_v<C>` is `false`.
40
 
41
  ### Exceptions <a id="thread.req.exception">[[thread.req.exception]]</a>
42
 
43
  Some functions described in this Clause are specified to throw
44
  exceptions of type `system_error` [[syserr.syserr]]. Such exceptions are
 
46
  to an operating system or other underlying API results in an error that
47
  prevents the library function from meeting its specifications. Failure
48
  to allocate storage is reported as described in 
49
  [[res.on.exception.handling]].
50
 
51
+ [*Example 1*: Consider a function in this Clause that is specified to
52
  throw exceptions of type `system_error` and specifies error conditions
53
  that include `operation_not_permitted` for a thread that does not have
54
  the privilege to perform the operation. Assume that, during the
55
  execution of this function, an `errno` of `EPERM` is reported by a POSIX
56
  API call used by the implementation. Since POSIX specifies an `errno` of
 
88
  as duration Dₘ. The delay durations may vary from timeout to timeout,
89
  but in all cases shorter is better.
90
 
91
  The functions whose names end in `_for` take an argument that specifies
92
  a duration. These functions produce relative timeouts. Implementations
93
+ should use a steady clock to measure time for these functions.[^1]
94
+
95
+ Given a duration argument Dₜ, the real-time duration of the timeout is
96
  Dₜ + Dᵢ + Dₘ.
97
 
98
  The functions whose names end in `_until` take an argument that
99
  specifies a time point. These functions produce absolute timeouts.
100
  Implementations should use the clock specified in the time point to
 
102
  the clock time point of the return from timeout should be Cₜ + Dᵢ + Dₘ
103
  when the clock is not adjusted during the timeout. If the clock is
104
  adjusted to the time Cₐ during the timeout, the behavior should be as
105
  follows:
106
 
107
+ - If Cₐ > Cₜ, the waiting function should wake as soon as possible,
108
  i.e., Cₐ + Dᵢ + Dₘ, since the timeout is already satisfied. This
109
  specification may result in the total duration of the wait decreasing
110
  when measured against a steady clock.
111
+ - If Cₐ ≤ Cₜ, the waiting function should not time out until
112
  `Clock::now()` returns a time Cₙ ≥ Cₜ, i.e., waking at Cₜ + Dᵢ + Dₘ.
113
  \[*Note 1*: When the clock is adjusted backwards, this specification
114
  can result in the total duration of the wait increasing when measured
115
  against a steady clock. When the clock is adjusted forwards, this
116
  specification can result in the total duration of the wait decreasing
 
119
  An implementation returns from such a timeout at any point from the time
120
  specified above to the time it would return from a steady-clock relative
121
  timeout on the difference between Cₜ and the time point of the call to
122
  the `_until` function.
123
 
124
+ *Recommended practice:* Implementations should decrease the duration of
125
+ the wait when the clock is adjusted forwards.
126
 
127
+ [*Note 2*: If the clock is not synchronized with a steady clock, e.g.,
128
+ a CPU time clock, these timeouts can fail to provide useful
129
  functionality. — *end note*]
130
 
131
  The resolution of timing provided by an implementation depends on both
132
  operating system and hardware. The finest resolution provided by an
133
  implementation is called the *native resolution*.
 
138
  A function that takes an argument which specifies a timeout will throw
139
  if, during its execution, a clock, time point, or time duration throws
140
  an exception. Such exceptions are referred to as *timeout-related
141
  exceptions*.
142
 
143
+ [*Note 3*: Instantiations of clock, time point and duration types
144
  supplied by the implementation as specified in  [[time.clock]] do not
145
  throw exceptions. — *end note*]
146
 
147
  ### Requirements for *Cpp17Lockable* types <a id="thread.req.lockable">[[thread.req.lockable]]</a>
148
 
 
165
  `shared_lock` [[thread.lock.shared]], `scoped_lock`
166
  [[thread.lock.scoped]], `lock_guard` [[thread.lock.guard]], `lock`,
167
  `try_lock` [[thread.lock.algorithm]], and `condition_variable_any`
168
  [[thread.condition.condvarany]] all operate on user-supplied lockable
169
  objects. The *Cpp17BasicLockable* requirements, the *Cpp17Lockable*
170
+ requirements, the *Cpp17TimedLockable* requirements, the
171
+ *Cpp17SharedLockable* requirements, and the *Cpp17SharedTimedLockable*
172
+ requirements list the requirements imposed by these library types in
173
+ order to acquire or release ownership of a `lock` by a given execution
174
+ agent.
175
 
176
  [*Note 3*: The nature of any lock ownership and any synchronization it
177
  entails are not part of these requirements. — *end note*]
178
 
179
+ A lock on an object `m` is said to be
180
+
181
+ - a *non-shared lock* if it is acquired by a call to `lock`, `try_lock`,
182
+ `try_lock_for`, or `try_lock_until` on `m`, or
183
+ - a *shared lock* if it is acquired by a call to `lock_shared`,
184
+ `try_lock_shared`, `try_lock_shared_for`, or `try_lock_shared_until`
185
+ on `m`.
186
+
187
+ [*Note 4*: Only the method of lock acquisition is considered; the
188
+ nature of any lock ownership is not part of these
189
+ definitions. — *end note*]
190
+
191
  #### *Cpp17BasicLockable* requirements <a id="thread.req.lockable.basic">[[thread.req.lockable.basic]]</a>
192
 
193
  A type `L` meets the *Cpp17BasicLockable* requirements if the following
194
  expressions are well-formed and have the specified semantics (`m`
195
  denotes a value of type `L`).
 
204
 
205
  ``` cpp
206
  m.unlock()
207
  ```
208
 
209
+ *Preconditions:* The current execution agent holds a non-shared lock on
210
+ `m`.
211
 
212
+ *Effects:* Releases a non-shared lock on `m` held by the current
213
+ execution agent.
214
 
215
  *Throws:* Nothing.
216
 
217
  #### *Cpp17Lockable* requirements <a id="thread.req.lockable.req">[[thread.req.lockable.req]]</a>
218
 
 
229
  without blocking. If an exception is thrown then a lock shall not have
230
  been acquired for the current execution agent.
231
 
232
  *Return type:* `bool`.
233
 
234
+ *Returns:* `true` if the lock was acquired, otherwise `false`.
235
 
236
  #### *Cpp17TimedLockable* requirements <a id="thread.req.lockable.timed">[[thread.req.lockable.timed]]</a>
237
 
238
  A type `L` meets the *Cpp17TimedLockable* requirements if it meets the
239
  *Cpp17Lockable* requirements and the following expressions are
 
253
  execution agent. If an exception is thrown then a lock has not been
254
  acquired for the current execution agent.
255
 
256
  *Return type:* `bool`.
257
 
258
+ *Returns:* `true` if the lock was acquired, otherwise `false`.
259
 
260
  ``` cpp
261
  m.try_lock_until(abs_time)
262
  ```
263
 
 
268
  execution agent. If an exception is thrown then a lock has not been
269
  acquired for the current execution agent.
270
 
271
  *Return type:* `bool`.
272
 
273
+ *Returns:* `true` if the lock was acquired, otherwise `false`.
274
+
275
+ #### *Cpp17SharedLockable* requirements <a id="thread.req.lockable.shared">[[thread.req.lockable.shared]]</a>
276
+
277
+ A type `L` meets the *Cpp17SharedLockable* requirements if the following
278
+ expressions are well-formed, have the specified semantics, and the
279
+ expression `m.try_lock_shared()` has type `bool` (`m` denotes a value of
280
+ type `L`):
281
+
282
+ ``` cpp
283
+ m.lock_shared()
284
+ ```
285
+
286
+ *Effects:* Blocks until a lock can be acquired for the current execution
287
+ agent. If an exception is thrown then a lock shall not have been
288
+ acquired for the current execution agent.
289
+
290
+ ``` cpp
291
+ m.try_lock_shared()
292
+ ```
293
+
294
+ *Effects:* Attempts to acquire a lock for the current execution agent
295
+ without blocking. If an exception is thrown then a lock shall not have
296
+ been acquired for the current execution agent.
297
+
298
+ *Returns:* `true` if the lock was acquired, `false` otherwise.
299
+
300
+ ``` cpp
301
+ m.unlock_shared()
302
+ ```
303
+
304
+ *Preconditions:* The current execution agent holds a shared lock on `m`.
305
+
306
+ *Effects:* Releases a shared lock on `m` held by the current execution
307
+ agent.
308
+
309
+ *Throws:* Nothing.
310
+
311
+ #### *Cpp17SharedTimedLockable* requirements <a id="thread.req.lockable.shared.timed">[[thread.req.lockable.shared.timed]]</a>
312
+
313
+ A type `L` meets the *Cpp17SharedTimedLockable* requirements if it meets
314
+ the *Cpp17SharedLockable* requirements, and the following expressions
315
+ are well-formed, have type `bool`, and have the specified semantics (`m`
316
+ denotes a value of type `L`, `rel_time` denotes a value of a
317
+ specialization of `chrono::duration`, and `abs_time` denotes a value of
318
+ a specialization of `chrono::time_point`).
319
+
320
+ ``` cpp
321
+ m.try_lock_shared_for(rel_time)
322
+ ```
323
+
324
+ *Effects:* Attempts to acquire a lock for the current execution agent
325
+ within the relative timeout [[thread.req.timing]] specified by
326
+ `rel_time`. The function will not return within the timeout specified by
327
+ `rel_time` unless it has obtained a lock on `m` for the current
328
+ execution agent. If an exception is thrown then a lock has not been
329
+ acquired for the current execution agent.
330
+
331
+ *Returns:* `true` if the lock was acquired, `false` otherwise.
332
+
333
+ ``` cpp
334
+ m.try_lock_shared_until(abs_time)
335
+ ```
336
+
337
+ *Effects:* Attempts to acquire a lock for the current execution agent
338
+ before the absolute timeout [[thread.req.timing]] specified by
339
+ `abs_time`. The function will not return before the timeout specified by
340
+ `abs_time` unless it has obtained a lock on `m` for the current
341
+ execution agent. If an exception is thrown then a lock has not been
342
+ acquired for the current execution agent.
343
+
344
  *Returns:* `true` if the lock was acquired, `false` otherwise.
345
 
346
  ## Stop tokens <a id="thread.stoptoken">[[thread.stoptoken]]</a>
347
 
348
  ### Introduction <a id="thread.stoptoken.intro">[[thread.stoptoken.intro]]</a>
349
 
350
+ Subclause [[thread.stoptoken]] describes components that can be used to
351
+ asynchronously request that an operation stops execution in a timely
352
+ manner, typically because the result is no longer required. Such a
353
+ request is called a *stop request*.
354
 
355
  `stop_source`, `stop_token`, and `stop_callback` implement semantics of
356
  shared ownership of a *stop state*. Any `stop_source`, `stop_token`, or
357
  `stop_callback` that shares ownership of the same stop state is an
358
  *associated* `stop_source`, `stop_token`, or `stop_callback`,
 
394
  struct nostopstate_t {
395
  explicit nostopstate_t() = default;
396
  };
397
  inline constexpr nostopstate_t nostopstate{};
398
 
399
+ // [stopcallback], class template stop_callback
400
  template<class Callback>
401
  class stop_callback;
402
  }
403
  ```
404
 
405
  ### Class `stop_token` <a id="stoptoken">[[stoptoken]]</a>
406
 
407
+ #### General <a id="stoptoken.general">[[stoptoken.general]]</a>
408
+
409
  The class `stop_token` provides an interface for querying whether a stop
410
  request has been made (`stop_requested`) or can ever be made
411
+ (`stop_possible`) using an associated `stop_source` object
412
+ [[stopsource]]. A `stop_token` can also be passed to a `stop_callback`
413
  [[stopcallback]] constructor to register a callback to be called when a
414
  stop request has been made from an associated `stop_source`.
415
 
416
  ``` cpp
417
  namespace std {
 
531
 
532
  *Effects:* Equivalent to: `x.swap(y)`.
533
 
534
  ### Class `stop_source` <a id="stopsource">[[stopsource]]</a>
535
 
536
+ #### General <a id="stopsource.general">[[stopsource.general]]</a>
537
+
538
  The class `stop_source` implements the semantics of making a stop
539
  request. A stop request made on a `stop_source` object is visible to all
540
+ associated `stop_source` and `stop_token` [[stoptoken]] objects. Once a
541
+ stop request has been made it cannot be withdrawn (a subsequent stop
542
  request has no effect).
543
 
544
  ``` cpp
545
  namespace std {
546
  // no-shared-stop-state indicator
 
584
  *Effects:* Initialises `*this` to have ownership of a new stop state.
585
 
586
  *Ensures:* `stop_possible()` is `true` and `stop_requested()` is
587
  `false`.
588
 
589
+ *Throws:* `bad_alloc` if memory cannot be allocated for the stop state.
 
590
 
591
  ``` cpp
592
  explicit stop_source(nostopstate_t) noexcept;
593
  ```
594
 
 
673
  has received a stop request, and if not, makes a stop request. The
674
  determination and making of the stop request are an atomic
675
  read-modify-write operation [[intro.races]]. If the request was made,
676
  the callbacks registered by associated `stop_callback` objects are
677
  synchronously called. If an invocation of a callback exits via an
678
+ exception then `terminate` is invoked [[except.terminate]].
679
 
680
  [*Note 1*: A stop request includes notifying all condition variables of
681
  type `condition_variable_any` temporarily registered during an
682
  interruptible wait [[thread.condvarany.intwait]]. — *end note*]
683
 
 
702
 
703
  *Effects:* Equivalent to: `x.swap(y)`.
704
 
705
  ### Class template `stop_callback` <a id="stopcallback">[[stopcallback]]</a>
706
 
707
+ #### General <a id="stopcallback.general">[[stopcallback.general]]</a>
708
+
709
  ``` cpp
710
  namespace std {
711
  template<class Callback>
712
  class stop_callback {
713
  public:
 
768
  stop state, acquires shared ownership of that stop state and registers
769
  the callback with that stop state such that
770
  `std::forward<Callback>(callback)()` is evaluated by the first call to
771
  `request_stop()` on an associated `stop_source`.
772
 
 
 
 
773
  *Throws:* Any exception thrown by the initialization of `callback`.
774
 
775
+ *Remarks:* If evaluating `std::forward<Callback>(callback)()` exits via
776
+ an exception, then `terminate` is invoked [[except.terminate]].
777
+
778
  ``` cpp
779
  ~stop_callback();
780
  ```
781
 
782
  *Effects:* Unregisters the callback from the owned stop state, if any.
 
789
  the return from the invocation of `callback`. Releases ownership of the
790
  stop state, if any.
791
 
792
  ## Threads <a id="thread.threads">[[thread.threads]]</a>
793
 
794
+ ### General <a id="thread.threads.general">[[thread.threads.general]]</a>
795
+
796
  [[thread.threads]] describes components that can be used to create and
797
  manage threads.
798
 
799
  [*Note 1*: These threads are intended to map one-to-one with operating
800
  system threads. — *end note*]
801
 
802
  ### Header `<thread>` synopsis <a id="thread.syn">[[thread.syn]]</a>
803
 
804
  ``` cpp
805
  #include <compare> // see [compare.syn]
 
806
 
807
  namespace std {
808
+ // [thread.thread.class], class thread
809
  class thread;
810
 
811
  void swap(thread& x, thread& y) noexcept;
812
 
813
+ // [thread.jthread.class], class jthread
814
  class jthread;
815
 
816
+ // [thread.thread.this], namespace this_thread
817
  namespace this_thread {
818
  thread::id get_id() noexcept;
819
 
820
  void yield() noexcept;
821
  template<class Clock, class Duration>
 
826
  }
827
  ```
828
 
829
  ### Class `thread` <a id="thread.thread.class">[[thread.thread.class]]</a>
830
 
831
+ #### General <a id="thread.thread.class.general">[[thread.thread.class.general]]</a>
832
+
833
  The class `thread` provides a mechanism to create a new thread of
834
  execution, to join with a thread (i.e., wait for a thread to complete),
835
  and to perform other operations that manage and query the state of a
836
  thread. A `thread` object uniquely represents a particular thread of
837
  execution. That representation may be transferred to other `thread`
 
847
 
848
  ``` cpp
849
  namespace std {
850
  class thread {
851
  public:
852
+ // [thread.thread.id], class thread::id
853
  class id;
854
  using native_handle_type = implementation-defined; // see~[thread.req.native]
855
 
856
  // construct/copy/destroy
857
  thread() noexcept;
 
860
  thread(const thread&) = delete;
861
  thread(thread&&) noexcept;
862
  thread& operator=(const thread&) = delete;
863
  thread& operator=(thread&&) noexcept;
864
 
865
+ // [thread.thread.member], members
866
  void swap(thread&) noexcept;
867
  bool joinable() const noexcept;
868
  void join();
869
  void detach();
870
  id get_id() const noexcept;
 
890
 
891
  template<class charT, class traits>
892
  basic_ostream<charT, traits>&
893
  operator<<(basic_ostream<charT, traits>& out, thread::id id);
894
 
895
+ template<class charT> struct formatter<thread::id, charT>;
896
+
897
  // hash support
898
  template<class T> struct hash;
899
  template<> struct hash<thread::id>;
900
  }
901
  ```
 
906
  Each thread of execution has an associated `thread::id` object that is
907
  not equal to the `thread::id` object of any other thread of execution
908
  and that is not equal to the `thread::id` object of any `thread` object
909
  that does not represent threads of execution.
910
 
911
+ The *text representation* for the character type `charT` of an object of
912
+ type `thread::id` is an unspecified sequence of `charT` such that, for
913
+ two objects of type `thread::id` `x` and `y`, if `x == y` is `true`, the
914
+ `thread::id` objects have the same text representation, and if `x != y`
915
+ is `true`, the `thread::id` objects have distinct text representations.
916
+
917
  `thread::id` is a trivially copyable class [[class.prop]]. The library
918
  may reuse the value of a `thread::id` of a terminated thread that can no
919
  longer be joined.
920
 
921
  [*Note 1*: Relational operators allow `thread::id` objects to be used
 
950
  template<class charT, class traits>
951
  basic_ostream<charT, traits>&
952
  operator<< (basic_ostream<charT, traits>& out, thread::id id);
953
  ```
954
 
955
+ *Effects:* Inserts the text representation for `charT` of `id` into
956
+ `out`.
 
 
957
 
958
  *Returns:* `out`.
959
 
960
+ ``` cpp
961
+ template<class charT> struct formatter<thread::id, charT>;
962
+ ```
963
+
964
+ `formatter<thread::id, charT>` interprets *format-spec* as a
965
+ *thread-id-format-spec*. The syntax of format specifications is as
966
+ follows:
967
+
968
+ ``` bnf
969
+ thread-id-format-spec
970
+ fill-and-alignₒₚₜ widthₒₚₜ
971
+ ```
972
+
973
+ [*Note 1*: The productions *fill-and-align* and *width* are described
974
+ in [[format.string.std]]. — *end note*]
975
+
976
+ If the *align* option is omitted it defaults to `>`.
977
+
978
+ A `thread::id` object is formatted by writing its text representation
979
+ for `charT` to the output with additional padding and adjustments as
980
+ specified by the format specifiers.
981
+
982
  ``` cpp
983
  template<> struct hash<thread::id>;
984
  ```
985
 
986
  The specialization is enabled [[unord.hash]].
 
1002
  *Constraints:* `remove_cvref_t<F>` is not the same type as `thread`.
1003
 
1004
  *Mandates:* The following are all `true`:
1005
 
1006
  - `is_constructible_v<decay_t<F>, F>`,
1007
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`, and
 
 
1008
  - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
1009
 
 
 
 
1010
  *Effects:* The new thread of execution executes
1011
 
1012
  ``` cpp
1013
+ invoke(auto(std::forward<F>(f)), // for invoke, see [func.invoke]
1014
+ auto(std::forward<Args>(args))...)
1015
  ```
1016
 
1017
+ with the values produced by `auto` being materialized [[conv.rval]] in
1018
+ the constructing thread. Any return value from this invocation is
1019
+ ignored.
1020
 
1021
  [*Note 1*: This implies that any exceptions not thrown from the
1022
  invocation of the copy of `f` will be thrown in the constructing thread,
1023
  not the new thread. — *end note*]
1024
 
1025
  If the invocation of `invoke` terminates with an uncaught exception,
1026
+ `terminate` is invoked [[except.terminate]].
1027
 
1028
  *Synchronization:* The completion of the invocation of the constructor
1029
  synchronizes with the beginning of the invocation of the copy of `f`.
1030
 
1031
  *Ensures:* `get_id() != id()`. `*this` represents the newly started
 
1050
 
1051
  ``` cpp
1052
  ~thread();
1053
  ```
1054
 
1055
+ *Effects:* If `joinable()`, invokes `terminate` [[except.terminate]].
1056
+ Otherwise, has no effects.
1057
 
1058
  [*Note 1*: Either implicitly detaching or joining a `joinable()` thread
1059
+ in its destructor can result in difficult to debug correctness (for
1060
  detach) or performance (for join) bugs encountered only when an
1061
+ exception is thrown. These bugs can be avoided by ensuring that the
1062
+ destructor is never executed while the thread is still
1063
+ joinable. — *end note*]
1064
 
1065
  #### Assignment <a id="thread.thread.assign">[[thread.thread.assign]]</a>
1066
 
1067
  ``` cpp
1068
  thread& operator=(thread&& x) noexcept;
1069
  ```
1070
 
1071
+ *Effects:* If `joinable()`, invokes `terminate` [[except.terminate]].
1072
+ Otherwise, assigns the state of `x` to `*this` and sets `x` to a default
1073
+ constructed state.
1074
 
1075
  *Ensures:* `x.get_id() == id()` and `get_id()` returns the value of
1076
  `x.get_id()` prior to the assignment.
1077
 
1078
  *Returns:* `*this`.
 
1166
 
1167
  *Effects:* As if by `x.swap(y)`.
1168
 
1169
  ### Class `jthread` <a id="thread.jthread.class">[[thread.jthread.class]]</a>
1170
 
1171
+ #### General <a id="thread.jthread.class.general">[[thread.jthread.class.general]]</a>
1172
+
1173
  The class `jthread` provides a mechanism to create a new thread of
1174
  execution. The functionality is the same as for class `thread`
1175
  [[thread.thread.class]] with the additional abilities to provide a
1176
  `stop_token` [[thread.stoptoken]] to the new thread of execution, make
1177
  stop requests, and automatically join.
 
1237
  *Constraints:* `remove_cvref_t<F>` is not the same type as `jthread`.
1238
 
1239
  *Mandates:* The following are all `true`:
1240
 
1241
  - `is_constructible_v<decay_t<F>, F>`,
1242
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`, and
 
 
1243
  - `is_invocable_v<decay_t<F>, decay_t<Args>...> ||`
1244
  `is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>`.
1245
 
 
 
 
1246
  *Effects:* Initializes `ssource`. The new thread of execution executes
1247
 
1248
  ``` cpp
1249
+ invoke(auto(std::forward<F>(f)), get_stop_token(), // for invoke, see [func.invoke]
1250
+ auto(std::forward<Args>(args))...)
1251
  ```
1252
 
1253
  if that expression is well-formed, otherwise
1254
 
1255
  ``` cpp
1256
+ invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)
1257
  ```
1258
 
1259
+ with the values produced by `auto` being materialized [[conv.rval]] in
1260
+ the constructing thread. Any return value from this invocation is
1261
+ ignored.
1262
 
1263
  [*Note 1*: This implies that any exceptions not thrown from the
1264
  invocation of the copy of `f` will be thrown in the constructing thread,
1265
  not the new thread. — *end note*]
1266
 
 
1304
 
1305
  ``` cpp
1306
  jthread& operator=(jthread&& x) noexcept;
1307
  ```
1308
 
1309
+ *Effects:* If `&x == this` is `true`, there are no effects. Otherwise,
1310
+ if `joinable()` is `true`, calls `request_stop()` and then `join()`,
1311
+ then assigns the state of `x` to `*this` and sets `x` to a default
1312
  constructed state.
1313
 
1314
+ *Ensures:* `get_id()` returns the value of `x.get_id()` prior to the
1315
+ assignment. `ssource` has the value of `x.ssource` prior to the
1316
+ assignment.
 
1317
 
1318
  *Returns:* `*this`.
1319
 
1320
  #### Members <a id="thread.jthread.mem">[[thread.jthread.mem]]</a>
1321
 
 
1437
  ``` cpp
1438
  thread::id this_thread::get_id() noexcept;
1439
  ```
1440
 
1441
  *Returns:* An object of type `thread::id` that uniquely identifies the
1442
+ current thread of execution. Every invocation from this thread of
1443
+ execution returns the same value. The object returned does not compare
1444
+ equal to a default-constructed `thread::id`.
1445
 
1446
  ``` cpp
1447
  void this_thread::yield() noexcept;
1448
  ```
1449
 
 
1473
 
1474
  *Synchronization:* None.
1475
 
1476
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
1477
 
1478
+ ## Atomic operations <a id="atomics">[[atomics]]</a>
1479
+
1480
+ ### General <a id="atomics.general">[[atomics.general]]</a>
1481
+
1482
+ Subclause [[atomics]] describes components for fine-grained atomic
1483
+ access. This access is provided via operations on atomic objects.
1484
+
1485
+ ### Header `<atomic>` synopsis <a id="atomics.syn">[[atomics.syn]]</a>
1486
+
1487
+ ``` cpp
1488
+ namespace std {
1489
+ // [atomics.order], order and consistency
1490
+ enum class memory_order : unspecified; // freestanding
1491
+ inline constexpr memory_order memory_order_relaxed = memory_order::relaxed; // freestanding
1492
+ inline constexpr memory_order memory_order_consume = memory_order::consume; // freestanding
1493
+ inline constexpr memory_order memory_order_acquire = memory_order::acquire; // freestanding
1494
+ inline constexpr memory_order memory_order_release = memory_order::release; // freestanding
1495
+ inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel; // freestanding
1496
+ inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst; // freestanding
1497
+
1498
+ template<class T>
1499
+ T kill_dependency(T y) noexcept; // freestanding
1500
+ }
1501
+
1502
+ // [atomics.lockfree], lock-free property
1503
+ #define ATOMIC_BOOL_LOCK_FREE unspecified // freestanding
1504
+ #define ATOMIC_CHAR_LOCK_FREE unspecified // freestanding
1505
+ #define ATOMIC_CHAR8_T_LOCK_FREE unspecified // freestanding
1506
+ #define ATOMIC_CHAR16_T_LOCK_FREE unspecified // freestanding
1507
+ #define ATOMIC_CHAR32_T_LOCK_FREE unspecified // freestanding
1508
+ #define ATOMIC_WCHAR_T_LOCK_FREE unspecified // freestanding
1509
+ #define ATOMIC_SHORT_LOCK_FREE unspecified // freestanding
1510
+ #define ATOMIC_INT_LOCK_FREE unspecified // freestanding
1511
+ #define ATOMIC_LONG_LOCK_FREE unspecified // freestanding
1512
+ #define ATOMIC_LLONG_LOCK_FREE unspecified // freestanding
1513
+ #define ATOMIC_POINTER_LOCK_FREE unspecified // freestanding
1514
+
1515
+ namespace std {
1516
+ // [atomics.ref.generic], class template atomic_ref
1517
+ template<class T> struct atomic_ref; // freestanding
1518
+ // [atomics.ref.pointer], partial specialization for pointers
1519
+ template<class T> struct atomic_ref<T*>; // freestanding
1520
+
1521
+ // [atomics.types.generic], class template atomic
1522
+ template<class T> struct atomic; // freestanding
1523
+ // [atomics.types.pointer], partial specialization for pointers
1524
+ template<class T> struct atomic<T*>; // freestanding
1525
+
1526
+ // [atomics.nonmembers], non-member functions
1527
+ template<class T>
1528
+ bool atomic_is_lock_free(const volatile atomic<T>*) noexcept; // freestanding
1529
+ template<class T>
1530
+ bool atomic_is_lock_free(const atomic<T>*) noexcept; // freestanding
1531
+ template<class T>
1532
+ void atomic_store(volatile atomic<T>*, // freestanding
1533
+ typename atomic<T>::value_type) noexcept;
1534
+ template<class T>
1535
+ void atomic_store(atomic<T>*, typename atomic<T>::value_type) noexcept; // freestanding
1536
+ template<class T>
1537
+ void atomic_store_explicit(volatile atomic<T>*, // freestanding
1538
+ typename atomic<T>::value_type,
1539
+ memory_order) noexcept;
1540
+ template<class T>
1541
+ void atomic_store_explicit(atomic<T>*, typename atomic<T>::value_type, // freestanding
1542
+ memory_order) noexcept;
1543
+ template<class T>
1544
+ T atomic_load(const volatile atomic<T>*) noexcept; // freestanding
1545
+ template<class T>
1546
+ T atomic_load(const atomic<T>*) noexcept; // freestanding
1547
+ template<class T>
1548
+ T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept; // freestanding
1549
+ template<class T>
1550
+ T atomic_load_explicit(const atomic<T>*, memory_order) noexcept; // freestanding
1551
+ template<class T>
1552
+ T atomic_exchange(volatile atomic<T>*, // freestanding
1553
+ typename atomic<T>::value_type) noexcept;
1554
+ template<class T>
1555
+ T atomic_exchange(atomic<T>*, typename atomic<T>::value_type) noexcept; // freestanding
1556
+ template<class T>
1557
+ T atomic_exchange_explicit(volatile atomic<T>*, // freestanding
1558
+ typename atomic<T>::value_type,
1559
+ memory_order) noexcept;
1560
+ template<class T>
1561
+ T atomic_exchange_explicit(atomic<T>*, typename atomic<T>::value_type, // freestanding
1562
+ memory_order) noexcept;
1563
+ template<class T>
1564
+ bool atomic_compare_exchange_weak(volatile atomic<T>*, // freestanding
1565
+ typename atomic<T>::value_type*,
1566
+ typename atomic<T>::value_type) noexcept;
1567
+ template<class T>
1568
+ bool atomic_compare_exchange_weak(atomic<T>*, // freestanding
1569
+ typename atomic<T>::value_type*,
1570
+ typename atomic<T>::value_type) noexcept;
1571
+ template<class T>
1572
+ bool atomic_compare_exchange_strong(volatile atomic<T>*, // freestanding
1573
+ typename atomic<T>::value_type*,
1574
+ typename atomic<T>::value_type) noexcept;
1575
+ template<class T>
1576
+ bool atomic_compare_exchange_strong(atomic<T>*, // freestanding
1577
+ typename atomic<T>::value_type*,
1578
+ typename atomic<T>::value_type) noexcept;
1579
+ template<class T>
1580
+ bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, // freestanding
1581
+ typename atomic<T>::value_type*,
1582
+ typename atomic<T>::value_type,
1583
+ memory_order, memory_order) noexcept;
1584
+ template<class T>
1585
+ bool atomic_compare_exchange_weak_explicit(atomic<T>*, // freestanding
1586
+ typename atomic<T>::value_type*,
1587
+ typename atomic<T>::value_type,
1588
+ memory_order, memory_order) noexcept;
1589
+ template<class T>
1590
+ bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, // freestanding
1591
+ typename atomic<T>::value_type*,
1592
+ typename atomic<T>::value_type,
1593
+ memory_order, memory_order) noexcept;
1594
+ template<class T>
1595
+ bool atomic_compare_exchange_strong_explicit(atomic<T>*, // freestanding
1596
+ typename atomic<T>::value_type*,
1597
+ typename atomic<T>::value_type,
1598
+ memory_order, memory_order) noexcept;
1599
+
1600
+ template<class T>
1601
+ T atomic_fetch_add(volatile atomic<T>*, // freestanding
1602
+ typename atomic<T>::difference_type) noexcept;
1603
+ template<class T>
1604
+ T atomic_fetch_add(atomic<T>*, typename atomic<T>::difference_type) noexcept; // freestanding
1605
+ template<class T>
1606
+ T atomic_fetch_add_explicit(volatile atomic<T>*, // freestanding
1607
+ typename atomic<T>::difference_type,
1608
+ memory_order) noexcept;
1609
+ template<class T>
1610
+ T atomic_fetch_add_explicit(atomic<T>*, typename atomic<T>::difference_type, // freestanding
1611
+ memory_order) noexcept;
1612
+ template<class T>
1613
+ T atomic_fetch_sub(volatile atomic<T>*, // freestanding
1614
+ typename atomic<T>::difference_type) noexcept;
1615
+ template<class T>
1616
+ T atomic_fetch_sub(atomic<T>*, typename atomic<T>::difference_type) noexcept; // freestanding
1617
+ template<class T>
1618
+ T atomic_fetch_sub_explicit(volatile atomic<T>*, // freestanding
1619
+ typename atomic<T>::difference_type,
1620
+ memory_order) noexcept;
1621
+ template<class T>
1622
+ T atomic_fetch_sub_explicit(atomic<T>*, typename atomic<T>::difference_type, // freestanding
1623
+ memory_order) noexcept;
1624
+ template<class T>
1625
+ T atomic_fetch_and(volatile atomic<T>*, // freestanding
1626
+ typename atomic<T>::value_type) noexcept;
1627
+ template<class T>
1628
+ T atomic_fetch_and(atomic<T>*, typename atomic<T>::value_type) noexcept; // freestanding
1629
+ template<class T>
1630
+ T atomic_fetch_and_explicit(volatile atomic<T>*, // freestanding
1631
+ typename atomic<T>::value_type,
1632
+ memory_order) noexcept;
1633
+ template<class T>
1634
+ T atomic_fetch_and_explicit(atomic<T>*, typename atomic<T>::value_type, // freestanding
1635
+ memory_order) noexcept;
1636
+ template<class T>
1637
+ T atomic_fetch_or(volatile atomic<T>*, // freestanding
1638
+ typename atomic<T>::value_type) noexcept;
1639
+ template<class T>
1640
+ T atomic_fetch_or(atomic<T>*, typename atomic<T>::value_type) noexcept; // freestanding
1641
+ template<class T>
1642
+ T atomic_fetch_or_explicit(volatile atomic<T>*, // freestanding
1643
+ typename atomic<T>::value_type,
1644
+ memory_order) noexcept;
1645
+ template<class T>
1646
+ T atomic_fetch_or_explicit(atomic<T>*, typename atomic<T>::value_type, // freestanding
1647
+ memory_order) noexcept;
1648
+ template<class T>
1649
+ T atomic_fetch_xor(volatile atomic<T>*, // freestanding
1650
+ typename atomic<T>::value_type) noexcept;
1651
+ template<class T>
1652
+ T atomic_fetch_xor(atomic<T>*, typename atomic<T>::value_type) noexcept; // freestanding
1653
+ template<class T>
1654
+ T atomic_fetch_xor_explicit(volatile atomic<T>*, // freestanding
1655
+ typename atomic<T>::value_type,
1656
+ memory_order) noexcept;
1657
+ template<class T>
1658
+ T atomic_fetch_xor_explicit(atomic<T>*, typename atomic<T>::value_type, // freestanding
1659
+ memory_order) noexcept;
1660
+
1661
+ template<class T>
1662
+ void atomic_wait(const volatile atomic<T>*, // freestanding
1663
+ typename atomic<T>::value_type) noexcept;
1664
+ template<class T>
1665
+ void atomic_wait(const atomic<T>*, typename atomic<T>::value_type) noexcept; // freestanding
1666
+ template<class T>
1667
+ void atomic_wait_explicit(const volatile atomic<T>*, // freestanding
1668
+ typename atomic<T>::value_type,
1669
+ memory_order) noexcept;
1670
+ template<class T>
1671
+ void atomic_wait_explicit(const atomic<T>*, typename atomic<T>::value_type, // freestanding
1672
+ memory_order) noexcept;
1673
+ template<class T>
1674
+ void atomic_notify_one(volatile atomic<T>*) noexcept; // freestanding
1675
+ template<class T>
1676
+ void atomic_notify_one(atomic<T>*) noexcept; // freestanding
1677
+ template<class T>
1678
+ void atomic_notify_all(volatile atomic<T>*) noexcept; // freestanding
1679
+ template<class T>
1680
+ void atomic_notify_all(atomic<T>*) noexcept; // freestanding
1681
+
1682
+ // [atomics.alias], type aliases
1683
+ using atomic_bool = atomic<bool>; // freestanding
1684
+ using atomic_char = atomic<char>; // freestanding
1685
+ using atomic_schar = atomic<signed char>; // freestanding
1686
+ using atomic_uchar = atomic<unsigned char>; // freestanding
1687
+ using atomic_short = atomic<short>; // freestanding
1688
+ using atomic_ushort = atomic<unsigned short>; // freestanding
1689
+ using atomic_int = atomic<int>; // freestanding
1690
+ using atomic_uint = atomic<unsigned int>; // freestanding
1691
+ using atomic_long = atomic<long>; // freestanding
1692
+ using atomic_ulong = atomic<unsigned long>; // freestanding
1693
+ using atomic_llong = atomic<long long>; // freestanding
1694
+ using atomic_ullong = atomic<unsigned long long>; // freestanding
1695
+ using atomic_char8_t = atomic<char8_t>; // freestanding
1696
+ using atomic_char16_t = atomic<char16_t>; // freestanding
1697
+ using atomic_char32_t = atomic<char32_t>; // freestanding
1698
+ using atomic_wchar_t = atomic<wchar_t>; // freestanding
1699
+
1700
+ using atomic_int8_t = atomic<int8_t>; // freestanding
1701
+ using atomic_uint8_t = atomic<uint8_t>; // freestanding
1702
+ using atomic_int16_t = atomic<int16_t>; // freestanding
1703
+ using atomic_uint16_t = atomic<uint16_t>; // freestanding
1704
+ using atomic_int32_t = atomic<int32_t>; // freestanding
1705
+ using atomic_uint32_t = atomic<uint32_t>; // freestanding
1706
+ using atomic_int64_t = atomic<int64_t>; // freestanding
1707
+ using atomic_uint64_t = atomic<uint64_t>; // freestanding
1708
+
1709
+ using atomic_int_least8_t = atomic<int_least8_t>; // freestanding
1710
+ using atomic_uint_least8_t = atomic<uint_least8_t>; // freestanding
1711
+ using atomic_int_least16_t = atomic<int_least16_t>; // freestanding
1712
+ using atomic_uint_least16_t = atomic<uint_least16_t>; // freestanding
1713
+ using atomic_int_least32_t = atomic<int_least32_t>; // freestanding
1714
+ using atomic_uint_least32_t = atomic<uint_least32_t>; // freestanding
1715
+ using atomic_int_least64_t = atomic<int_least64_t>; // freestanding
1716
+ using atomic_uint_least64_t = atomic<uint_least64_t>; // freestanding
1717
+
1718
+ using atomic_int_fast8_t = atomic<int_fast8_t>; // freestanding
1719
+ using atomic_uint_fast8_t = atomic<uint_fast8_t>; // freestanding
1720
+ using atomic_int_fast16_t = atomic<int_fast16_t>; // freestanding
1721
+ using atomic_uint_fast16_t = atomic<uint_fast16_t>; // freestanding
1722
+ using atomic_int_fast32_t = atomic<int_fast32_t>; // freestanding
1723
+ using atomic_uint_fast32_t = atomic<uint_fast32_t>; // freestanding
1724
+ using atomic_int_fast64_t = atomic<int_fast64_t>; // freestanding
1725
+ using atomic_uint_fast64_t = atomic<uint_fast64_t>; // freestanding
1726
+
1727
+ using atomic_intptr_t = atomic<intptr_t>; // freestanding
1728
+ using atomic_uintptr_t = atomic<uintptr_t>; // freestanding
1729
+ using atomic_size_t = atomic<size_t>; // freestanding
1730
+ using atomic_ptrdiff_t = atomic<ptrdiff_t>; // freestanding
1731
+ using atomic_intmax_t = atomic<intmax_t>; // freestanding
1732
+ using atomic_uintmax_t = atomic<uintmax_t>; // freestanding
1733
+
1734
+ using atomic_signed_lock_free = see below;
1735
+ using atomic_unsigned_lock_free = see below;
1736
+
1737
+ // [atomics.flag], flag type and operations
1738
+ struct atomic_flag; // freestanding
1739
+
1740
+ bool atomic_flag_test(const volatile atomic_flag*) noexcept; // freestanding
1741
+ bool atomic_flag_test(const atomic_flag*) noexcept; // freestanding
1742
+ bool atomic_flag_test_explicit(const volatile atomic_flag*, // freestanding
1743
+ memory_order) noexcept;
1744
+ bool atomic_flag_test_explicit(const atomic_flag*, memory_order) noexcept; // freestanding
1745
+ bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept; // freestanding
1746
+ bool atomic_flag_test_and_set(atomic_flag*) noexcept; // freestanding
1747
+ bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, // freestanding
1748
+ memory_order) noexcept;
1749
+ bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept; // freestanding
1750
+ void atomic_flag_clear(volatile atomic_flag*) noexcept; // freestanding
1751
+ void atomic_flag_clear(atomic_flag*) noexcept; // freestanding
1752
+ void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept; // freestanding
1753
+ void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept; // freestanding
1754
+
1755
+ void atomic_flag_wait(const volatile atomic_flag*, bool) noexcept; // freestanding
1756
+ void atomic_flag_wait(const atomic_flag*, bool) noexcept; // freestanding
1757
+ void atomic_flag_wait_explicit(const volatile atomic_flag*, // freestanding
1758
+ bool, memory_order) noexcept;
1759
+ void atomic_flag_wait_explicit(const atomic_flag*, // freestanding
1760
+ bool, memory_order) noexcept;
1761
+ void atomic_flag_notify_one(volatile atomic_flag*) noexcept; // freestanding
1762
+ void atomic_flag_notify_one(atomic_flag*) noexcept; // freestanding
1763
+ void atomic_flag_notify_all(volatile atomic_flag*) noexcept; // freestanding
1764
+ void atomic_flag_notify_all(atomic_flag*) noexcept; // freestanding
1765
+ #define ATOMIC_FLAG_INIT see belownc // freestanding
1766
+
1767
+ // [atomics.fences], fences
1768
+ extern "C" void atomic_thread_fence(memory_order) noexcept; // freestanding
1769
+ extern "C" void atomic_signal_fence(memory_order) noexcept; // freestanding
1770
+ }
1771
+ ```
1772
+
1773
+ ### Type aliases <a id="atomics.alias">[[atomics.alias]]</a>
1774
+
1775
+ The type aliases `atomic_intN_t`, `atomic_uintN_t`, `atomic_intptr_t`,
1776
+ and `atomic_uintptr_t` are defined if and only if `intN_t`, `uintN_t`,
1777
+ `intptr_t`, and `uintptr_t` are defined, respectively.
1778
+
1779
+ The type aliases `atomic_signed_lock_free` and
1780
+ `atomic_unsigned_lock_free` name specializations of `atomic` whose
1781
+ template arguments are integral types, respectively signed and unsigned,
1782
+ and whose `is_always_lock_free` property is `true`.
1783
+
1784
+ [*Note 1*: These aliases are optional in freestanding implementations
1785
+ [[compliance]]. — *end note*]
1786
+
1787
+ Implementations should choose for these aliases the integral
1788
+ specializations of `atomic` for which the atomic waiting and notifying
1789
+ operations [[atomics.wait]] are most efficient.
1790
+
1791
+ ### Order and consistency <a id="atomics.order">[[atomics.order]]</a>
1792
+
1793
+ ``` cpp
1794
+ namespace std {
1795
+ enum class memory_order : unspecified {
1796
+ relaxed, consume, acquire, release, acq_rel, seq_cst
1797
+ };
1798
+ }
1799
+ ```
1800
+
1801
+ The enumeration `memory_order` specifies the detailed regular
1802
+ (non-atomic) memory synchronization order as defined in
1803
+ [[intro.multithread]] and may provide for operation ordering. Its
1804
+ enumerated values and their meanings are as follows:
1805
+
1806
+ - `memory_order::relaxed`: no operation orders memory.
1807
+ - `memory_order::release`, `memory_order::acq_rel`, and
1808
+ `memory_order::seq_cst`: a store operation performs a release
1809
+ operation on the affected memory location.
1810
+ - `memory_order::consume`: a load operation performs a consume operation
1811
+ on the affected memory location. \[*Note 1*: Prefer
1812
+ `memory_order::acquire`, which provides stronger guarantees than
1813
+ `memory_order::consume`. Implementations have found it infeasible to
1814
+ provide performance better than that of `memory_order::acquire`.
1815
+ Specification revisions are under consideration. — *end note*]
1816
+ - `memory_order::acquire`, `memory_order::acq_rel`, and
1817
+ `memory_order::seq_cst`: a load operation performs an acquire
1818
+ operation on the affected memory location.
1819
+
1820
+ [*Note 2*: Atomic operations specifying `memory_order::relaxed` are
1821
+ relaxed with respect to memory ordering. Implementations must still
1822
+ guarantee that any given atomic access to a particular atomic object be
1823
+ indivisible with respect to all other atomic accesses to that
1824
+ object. — *end note*]
1825
+
1826
+ An atomic operation A that performs a release operation on an atomic
1827
+ object M synchronizes with an atomic operation B that performs an
1828
+ acquire operation on M and takes its value from any side effect in the
1829
+ release sequence headed by A.
1830
+
1831
+ An atomic operation A on some atomic object M is *coherence-ordered
1832
+ before* another atomic operation B on M if
1833
+
1834
+ - A is a modification, and B reads the value stored by A, or
1835
+ - A precedes B in the modification order of M, or
1836
+ - A and B are not the same atomic read-modify-write operation, and there
1837
+ exists an atomic modification X of M such that A reads the value
1838
+ stored by X and X precedes B in the modification order of M, or
1839
+ - there exists an atomic modification X of M such that A is
1840
+ coherence-ordered before X and X is coherence-ordered before B.
1841
+
1842
+ There is a single total order S on all `memory_order::seq_cst`
1843
+ operations, including fences, that satisfies the following constraints.
1844
+ First, if A and B are `memory_order::seq_cst` operations and A strongly
1845
+ happens before B, then A precedes B in S. Second, for every pair of
1846
+ atomic operations A and B on an object M, where A is coherence-ordered
1847
+ before B, the following four conditions are required to be satisfied by
1848
+ S:
1849
+
1850
+ - if A and B are both `memory_order::seq_cst` operations, then A
1851
+ precedes B in S; and
1852
+ - if A is a `memory_order::seq_cst` operation and B happens before a
1853
+ `memory_order::seq_cst` fence Y, then A precedes Y in S; and
1854
+ - if a `memory_order::seq_cst` fence X happens before A and B is a
1855
+ `memory_order::seq_cst` operation, then X precedes B in S; and
1856
+ - if a `memory_order::seq_cst` fence X happens before A and B happens
1857
+ before a `memory_order::seq_cst` fence Y, then X precedes Y in S.
1858
+
1859
+ [*Note 3*: This definition ensures that S is consistent with the
1860
+ modification order of any atomic object M. It also ensures that a
1861
+ `memory_order::seq_cst` load A of M gets its value either from the last
1862
+ modification of M that precedes A in S or from some
1863
+ non-`memory_order::seq_cst` modification of M that does not happen
1864
+ before any modification of M that precedes A in S. — *end note*]
1865
+
1866
+ [*Note 4*: We do not require that S be consistent with “happens before”
1867
+ [[intro.races]]. This allows more efficient implementation of
1868
+ `memory_order::acquire` and `memory_order::release` on some machine
1869
+ architectures. It can produce surprising results when these are mixed
1870
+ with `memory_order::seq_cst` accesses. — *end note*]
1871
+
1872
+ [*Note 5*: `memory_order::seq_cst` ensures sequential consistency only
1873
+ for a program that is free of data races and uses exclusively
1874
+ `memory_order::seq_cst` atomic operations. Any use of weaker ordering
1875
+ will invalidate this guarantee unless extreme care is used. In many
1876
+ cases, `memory_order::seq_cst` atomic operations are reorderable with
1877
+ respect to other atomic operations performed by the same
1878
+ thread. — *end note*]
1879
+
1880
+ Implementations should ensure that no “out-of-thin-air” values are
1881
+ computed that circularly depend on their own computation.
1882
+
1883
+ [*Note 6*:
1884
+
1885
+ For example, with `x` and `y` initially zero,
1886
+
1887
+ ``` cpp
1888
+ // Thread 1:
1889
+ r1 = y.load(memory_order::relaxed);
1890
+ x.store(r1, memory_order::relaxed);
1891
+ ```
1892
+
1893
+ ``` cpp
1894
+ // Thread 2:
1895
+ r2 = x.load(memory_order::relaxed);
1896
+ y.store(r2, memory_order::relaxed);
1897
+ ```
1898
+
1899
+ this recommendation discourages producing `r1 == r2 == 42`, since the
1900
+ store of 42 to `y` is only possible if the store to `x` stores `42`,
1901
+ which circularly depends on the store to `y` storing `42`. Note that
1902
+ without this restriction, such an execution is possible.
1903
+
1904
+ — *end note*]
1905
+
1906
+ [*Note 7*:
1907
+
1908
+ The recommendation similarly disallows `r1 == r2 == 42` in the following
1909
+ example, with `x` and `y` again initially zero:
1910
+
1911
+ ``` cpp
1912
+ // Thread 1:
1913
+ r1 = x.load(memory_order::relaxed);
1914
+ if (r1 == 42) y.store(42, memory_order::relaxed);
1915
+ ```
1916
+
1917
+ ``` cpp
1918
+ // Thread 2:
1919
+ r2 = y.load(memory_order::relaxed);
1920
+ if (r2 == 42) x.store(42, memory_order::relaxed);
1921
+ ```
1922
+
1923
+ — *end note*]
1924
+
1925
+ Atomic read-modify-write operations shall always read the last value (in
1926
+ the modification order) written before the write associated with the
1927
+ read-modify-write operation.
1928
+
1929
+ Implementations should make atomic stores visible to atomic loads within
1930
+ a reasonable amount of time.
1931
+
1932
+ ``` cpp
1933
+ template<class T>
1934
+ T kill_dependency(T y) noexcept;
1935
+ ```
1936
+
1937
+ *Effects:* The argument does not carry a dependency to the return
1938
+ value [[intro.multithread]].
1939
+
1940
+ *Returns:* `y`.
1941
+
1942
+ ### Lock-free property <a id="atomics.lockfree">[[atomics.lockfree]]</a>
1943
+
1944
+ ``` cpp
1945
+ #define ATOMIC_BOOL_LOCK_FREE unspecified
1946
+ #define ATOMIC_CHAR_LOCK_FREE unspecified
1947
+ #define ATOMIC_CHAR8_T_LOCK_FREE unspecified
1948
+ #define ATOMIC_CHAR16_T_LOCK_FREE unspecified
1949
+ #define ATOMIC_CHAR32_T_LOCK_FREE unspecified
1950
+ #define ATOMIC_WCHAR_T_LOCK_FREE unspecified
1951
+ #define ATOMIC_SHORT_LOCK_FREE unspecified
1952
+ #define ATOMIC_INT_LOCK_FREE unspecified
1953
+ #define ATOMIC_LONG_LOCK_FREE unspecified
1954
+ #define ATOMIC_LLONG_LOCK_FREE unspecified
1955
+ #define ATOMIC_POINTER_LOCK_FREE unspecified
1956
+ ```
1957
+
1958
+ The `ATOMIC_..._LOCK_FREE` macros indicate the lock-free property of the
1959
+ corresponding atomic types, with the signed and unsigned variants
1960
+ grouped together. The properties also apply to the corresponding
1961
+ (partial) specializations of the `atomic` template. A value of 0
1962
+ indicates that the types are never lock-free. A value of 1 indicates
1963
+ that the types are sometimes lock-free. A value of 2 indicates that the
1964
+ types are always lock-free.
1965
+
1966
+ On a hosted implementation [[compliance]], at least one signed integral
1967
+ specialization of the `atomic` template, along with the specialization
1968
+ for the corresponding unsigned type [[basic.fundamental]], is always
1969
+ lock-free.
1970
+
1971
+ The functions `atomic<T>::is_lock_free` and `atomic_is_lock_free`
1972
+ [[atomics.types.operations]] indicate whether the object is lock-free.
1973
+ In any given program execution, the result of the lock-free query is the
1974
+ same for all atomic objects of the same type.
1975
+
1976
+ Atomic operations that are not lock-free are considered to potentially
1977
+ block [[intro.progress]].
1978
+
1979
+ *Recommended practice:* Operations that are lock-free should also be
1980
+ address-free.[^2]
1981
+
1982
+ The implementation of these operations should not depend on any
1983
+ per-process state.
1984
+
1985
+ [*Note 1*: This restriction enables communication by memory that is
1986
+ mapped into a process more than once and by memory that is shared
1987
+ between two processes. — *end note*]
1988
+
1989
+ ### Waiting and notifying <a id="atomics.wait">[[atomics.wait]]</a>
1990
+
1991
+ *Atomic waiting operations* and *atomic notifying operations* provide a
1992
+ mechanism to wait for the value of an atomic object to change more
1993
+ efficiently than can be achieved with polling. An atomic waiting
1994
+ operation may block until it is unblocked by an atomic notifying
1995
+ operation, according to each function’s effects.
1996
+
1997
+ [*Note 1*: Programs are not guaranteed to observe transient atomic
1998
+ values, an issue known as the A-B-A problem, resulting in continued
1999
+ blocking if a condition is only temporarily met. — *end note*]
2000
+
2001
+ [*Note 2*:
2002
+
2003
+ The following functions are atomic waiting operations:
2004
+
2005
+ - `atomic<T>::wait`,
2006
+ - `atomic_flag::wait`,
2007
+ - `atomic_wait` and `atomic_wait_explicit`,
2008
+ - `atomic_flag_wait` and `atomic_flag_wait_explicit`, and
2009
+ - `atomic_ref<T>::wait`.
2010
+
2011
+ — *end note*]
2012
+
2013
+ [*Note 3*:
2014
+
2015
+ The following functions are atomic notifying operations:
2016
+
2017
+ - `atomic<T>::notify_one` and `atomic<T>::notify_all`,
2018
+ - `atomic_flag::notify_one` and `atomic_flag::notify_all`,
2019
+ - `atomic_notify_one` and `atomic_notify_all`,
2020
+ - `atomic_flag_notify_one` and `atomic_flag_notify_all`, and
2021
+ - `atomic_ref<T>::notify_one` and `atomic_ref<T>::notify_all`.
2022
+
2023
+ — *end note*]
2024
+
2025
+ A call to an atomic waiting operation on an atomic object `M` is
2026
+ *eligible to be unblocked* by a call to an atomic notifying operation on
2027
+ `M` if there exist side effects `X` and `Y` on `M` such that:
2028
+
2029
+ - the atomic waiting operation has blocked after observing the result of
2030
+ `X`,
2031
+ - `X` precedes `Y` in the modification order of `M`, and
2032
+ - `Y` happens before the call to the atomic notifying operation.
2033
+
2034
+ ### Class template `atomic_ref` <a id="atomics.ref.generic">[[atomics.ref.generic]]</a>
2035
+
2036
+ #### General <a id="atomics.ref.generic.general">[[atomics.ref.generic.general]]</a>
2037
+
2038
+ ``` cpp
2039
+ namespace std {
2040
+ template<class T> struct atomic_ref {
2041
+ private:
2042
+ T* ptr; // exposition only
2043
+
2044
+ public:
2045
+ using value_type = T;
2046
+ static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
2047
+
2048
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
2049
+ bool is_lock_free() const noexcept;
2050
+
2051
+ explicit atomic_ref(T&);
2052
+ atomic_ref(const atomic_ref&) noexcept;
2053
+ atomic_ref& operator=(const atomic_ref&) = delete;
2054
+
2055
+ void store(T, memory_order = memory_order::seq_cst) const noexcept;
2056
+ T operator=(T) const noexcept;
2057
+ T load(memory_order = memory_order::seq_cst) const noexcept;
2058
+ operator T() const noexcept;
2059
+
2060
+ T exchange(T, memory_order = memory_order::seq_cst) const noexcept;
2061
+ bool compare_exchange_weak(T&, T,
2062
+ memory_order, memory_order) const noexcept;
2063
+ bool compare_exchange_strong(T&, T,
2064
+ memory_order, memory_order) const noexcept;
2065
+ bool compare_exchange_weak(T&, T,
2066
+ memory_order = memory_order::seq_cst) const noexcept;
2067
+ bool compare_exchange_strong(T&, T,
2068
+ memory_order = memory_order::seq_cst) const noexcept;
2069
+
2070
+ void wait(T, memory_order = memory_order::seq_cst) const noexcept;
2071
+ void notify_one() const noexcept;
2072
+ void notify_all() const noexcept;
2073
+ };
2074
+ }
2075
+ ```
2076
+
2077
+ An `atomic_ref` object applies atomic operations [[atomics.general]] to
2078
+ the object referenced by `*ptr` such that, for the lifetime
2079
+ [[basic.life]] of the `atomic_ref` object, the object referenced by
2080
+ `*ptr` is an atomic object [[intro.races]].
2081
+
2082
+ The program is ill-formed if `is_trivially_copyable_v<T>` is `false`.
2083
+
2084
+ The lifetime [[basic.life]] of an object referenced by `*ptr` shall
2085
+ exceed the lifetime of all `atomic_ref`s that reference the object.
2086
+ While any `atomic_ref` instances exist that reference the `*ptr` object,
2087
+ all accesses to that object shall exclusively occur through those
2088
+ `atomic_ref` instances. No subobject of the object referenced by
2089
+ `atomic_ref` shall be concurrently referenced by any other `atomic_ref`
2090
+ object.
2091
+
2092
+ Atomic operations applied to an object through a referencing
2093
+ `atomic_ref` are atomic with respect to atomic operations applied
2094
+ through any other `atomic_ref` referencing the same object.
2095
+
2096
+ [*Note 1*: Atomic operations or the `atomic_ref` constructor can
2097
+ acquire a shared resource, such as a lock associated with the referenced
2098
+ object, to enable atomic operations to be applied to the referenced
2099
+ object. — *end note*]
2100
+
2101
+ #### Operations <a id="atomics.ref.ops">[[atomics.ref.ops]]</a>
2102
+
2103
+ ``` cpp
2104
+ static constexpr size_t required_alignment;
2105
+ ```
2106
+
2107
+ The alignment required for an object to be referenced by an atomic
2108
+ reference, which is at least `alignof(T)`.
2109
+
2110
+ [*Note 1*: Hardware could require an object referenced by an
2111
+ `atomic_ref` to have stricter alignment [[basic.align]] than other
2112
+ objects of type `T`. Further, whether operations on an `atomic_ref` are
2113
+ lock-free could depend on the alignment of the referenced object. For
2114
+ example, lock-free operations on `std::complex<double>` could be
2115
+ supported only if aligned to `2*alignof(double)`. — *end note*]
2116
+
2117
+ ``` cpp
2118
+ static constexpr bool is_always_lock_free;
2119
+ ```
2120
+
2121
+ The static data member `is_always_lock_free` is `true` if the
2122
+ `atomic_ref` type’s operations are always lock-free, and `false`
2123
+ otherwise.
2124
+
2125
+ ``` cpp
2126
+ bool is_lock_free() const noexcept;
2127
+ ```
2128
+
2129
+ *Returns:* `true` if operations on all objects of the type
2130
+ `atomic_ref<T>` are lock-free, `false` otherwise.
2131
+
2132
+ ``` cpp
2133
+ atomic_ref(T& obj);
2134
+ ```
2135
+
2136
+ *Preconditions:* The referenced object is aligned to
2137
+ `required_alignment`.
2138
+
2139
+ *Ensures:* `*this` references `obj`.
2140
+
2141
+ *Throws:* Nothing.
2142
+
2143
+ ``` cpp
2144
+ atomic_ref(const atomic_ref& ref) noexcept;
2145
+ ```
2146
+
2147
+ *Ensures:* `*this` references the object referenced by `ref`.
2148
+
2149
+ ``` cpp
2150
+ void store(T desired, memory_order order = memory_order::seq_cst) const noexcept;
2151
+ ```
2152
+
2153
+ *Preconditions:* The `order` argument is neither
2154
+ `memory_order::consume`, `memory_order::acquire`, nor
2155
+ `memory_order::acq_rel`.
2156
+
2157
+ *Effects:* Atomically replaces the value referenced by `*ptr` with the
2158
+ value of `desired`. Memory is affected according to the value of
2159
+ `order`.
2160
+
2161
+ ``` cpp
2162
+ T operator=(T desired) const noexcept;
2163
+ ```
2164
+
2165
+ *Effects:* Equivalent to:
2166
+
2167
+ ``` cpp
2168
+ store(desired);
2169
+ return desired;
2170
+ ```
2171
+
2172
+ ``` cpp
2173
+ T load(memory_order order = memory_order::seq_cst) const noexcept;
2174
+ ```
2175
+
2176
+ *Preconditions:* The `order` argument is neither `memory_order::release`
2177
+ nor `memory_order::acq_rel`.
2178
+
2179
+ *Effects:* Memory is affected according to the value of `order`.
2180
+
2181
+ *Returns:* Atomically returns the value referenced by `*ptr`.
2182
+
2183
+ ``` cpp
2184
+ operator T() const noexcept;
2185
+ ```
2186
+
2187
+ *Effects:* Equivalent to: `return load();`
2188
+
2189
+ ``` cpp
2190
+ T exchange(T desired, memory_order order = memory_order::seq_cst) const noexcept;
2191
+ ```
2192
+
2193
+ *Effects:* Atomically replaces the value referenced by `*ptr` with
2194
+ `desired`. Memory is affected according to the value of `order`. This
2195
+ operation is an atomic read-modify-write
2196
+ operation [[intro.multithread]].
2197
+
2198
+ *Returns:* Atomically returns the value referenced by `*ptr` immediately
2199
+ before the effects.
2200
+
2201
+ ``` cpp
2202
+ bool compare_exchange_weak(T& expected, T desired,
2203
+ memory_order success, memory_order failure) const noexcept;
2204
+
2205
+ bool compare_exchange_strong(T& expected, T desired,
2206
+ memory_order success, memory_order failure) const noexcept;
2207
+
2208
+ bool compare_exchange_weak(T& expected, T desired,
2209
+ memory_order order = memory_order::seq_cst) const noexcept;
2210
+
2211
+ bool compare_exchange_strong(T& expected, T desired,
2212
+ memory_order order = memory_order::seq_cst) const noexcept;
2213
+ ```
2214
+
2215
+ *Preconditions:* The `failure` argument is neither
2216
+ `memory_order::release` nor `memory_order::acq_rel`.
2217
+
2218
+ *Effects:* Retrieves the value in `expected`. It then atomically
2219
+ compares the value representation of the value referenced by `*ptr` for
2220
+ equality with that previously retrieved from `expected`, and if `true`,
2221
+ replaces the value referenced by `*ptr` with that in `desired`. If and
2222
+ only if the comparison is `true`, memory is affected according to the
2223
+ value of `success`, and if the comparison is `false`, memory is affected
2224
+ according to the value of `failure`. When only one `memory_order`
2225
+ argument is supplied, the value of `success` is `order`, and the value
2226
+ of `failure` is `order` except that a value of `memory_order::acq_rel`
2227
+ shall be replaced by the value `memory_order::acquire` and a value of
2228
+ `memory_order::release` shall be replaced by the value
2229
+ `memory_order::relaxed`. If and only if the comparison is `false` then,
2230
+ after the atomic operation, the value in `expected` is replaced by the
2231
+ value read from the value referenced by `*ptr` during the atomic
2232
+ comparison. If the operation returns `true`, these operations are atomic
2233
+ read-modify-write operations [[intro.races]] on the value referenced by
2234
+ `*ptr`. Otherwise, these operations are atomic load operations on that
2235
+ memory.
2236
+
2237
+ *Returns:* The result of the comparison.
2238
+
2239
+ *Remarks:* A weak compare-and-exchange operation may fail spuriously.
2240
+ That is, even when the contents of memory referred to by `expected` and
2241
+ `ptr` are equal, it may return `false` and store back to `expected` the
2242
+ same memory contents that were originally there.
2243
+
2244
+ [*Note 2*: This spurious failure enables implementation of
2245
+ compare-and-exchange on a broader class of machines, e.g., load-locked
2246
+ store-conditional machines. A consequence of spurious failure is that
2247
+ nearly all uses of weak compare-and-exchange will be in a loop. When a
2248
+ compare-and-exchange is in a loop, the weak version will yield better
2249
+ performance on some platforms. When a weak compare-and-exchange would
2250
+ require a loop and a strong one would not, the strong one is
2251
+ preferable. — *end note*]
2252
+
2253
+ ``` cpp
2254
+ void wait(T old, memory_order order = memory_order::seq_cst) const noexcept;
2255
+ ```
2256
+
2257
+ *Preconditions:* `order` is neither `memory_order::release` nor
2258
+ `memory_order::acq_rel`.
2259
+
2260
+ *Effects:* Repeatedly performs the following steps, in order:
2261
+
2262
+ - Evaluates `load(order)` and compares its value representation for
2263
+ equality against that of `old`.
2264
+ - If they compare unequal, returns.
2265
+ - Blocks until it is unblocked by an atomic notifying operation or is
2266
+ unblocked spuriously.
2267
+
2268
+ *Remarks:* This function is an atomic waiting operation [[atomics.wait]]
2269
+ on atomic object `*ptr`.
2270
+
2271
+ ``` cpp
2272
+ void notify_one() const noexcept;
2273
+ ```
2274
+
2275
+ *Effects:* Unblocks the execution of at least one atomic waiting
2276
+ operation on `*ptr` that is eligible to be unblocked [[atomics.wait]] by
2277
+ this call, if any such atomic waiting operations exist.
2278
+
2279
+ *Remarks:* This function is an atomic notifying
2280
+ operation [[atomics.wait]] on atomic object `*ptr`.
2281
+
2282
+ ``` cpp
2283
+ void notify_all() const noexcept;
2284
+ ```
2285
+
2286
+ *Effects:* Unblocks the execution of all atomic waiting operations on
2287
+ `*ptr` that are eligible to be unblocked [[atomics.wait]] by this call.
2288
+
2289
+ *Remarks:* This function is an atomic notifying
2290
+ operation [[atomics.wait]] on atomic object `*ptr`.
2291
+
2292
+ #### Specializations for integral types <a id="atomics.ref.int">[[atomics.ref.int]]</a>
2293
+
2294
+ There are specializations of the `atomic_ref` class template for the
2295
+ integral types `char`, `signed char`, `unsigned char`, `short`,
2296
+ `unsigned short`, `int`, `unsigned int`, `long`, `unsigned long`,
2297
+ `long long`, `unsigned long long`, `char8_t`, `char16_t`, `char32_t`,
2298
+ `wchar_t`, and any other types needed by the typedefs in the header
2299
+ `<cstdint>`. For each such type `integral-type`, the specialization
2300
+ `atomic_ref<integral-type>` provides additional atomic operations
2301
+ appropriate to integral types.
2302
+
2303
+ [*Note 1*: The specialization `atomic_ref<bool>` uses the primary
2304
+ template [[atomics.ref.generic]]. — *end note*]
2305
+
2306
+ ``` cpp
2307
+ namespace std {
2308
+ template<> struct atomic_ref<integral-type> {
2309
+ private:
2310
+ integral-type* ptr; // exposition only
2311
+
2312
+ public:
2313
+ using value_type = integral-type;
2314
+ using difference_type = value_type;
2315
+ static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
2316
+
2317
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
2318
+ bool is_lock_free() const noexcept;
2319
+
2320
+ explicit atomic_ref(integral-type&);
2321
+ atomic_ref(const atomic_ref&) noexcept;
2322
+ atomic_ref& operator=(const atomic_ref&) = delete;
2323
+
2324
+ void store(integral-type, memory_order = memory_order::seq_cst) const noexcept;
2325
+ integral-type operator=(integral-type) const noexcept;
2326
+ integral-type load(memory_order = memory_order::seq_cst) const noexcept;
2327
+ operator integral-type() const noexcept;
2328
+
2329
+ integral-type exchange(integral-type,
2330
+ memory_order = memory_order::seq_cst) const noexcept;
2331
+ bool compare_exchange_weak(integral-type&, integral-type,
2332
+ memory_order, memory_order) const noexcept;
2333
+ bool compare_exchange_strong(integral-type&, integral-type,
2334
+ memory_order, memory_order) const noexcept;
2335
+ bool compare_exchange_weak(integral-type&, integral-type,
2336
+ memory_order = memory_order::seq_cst) const noexcept;
2337
+ bool compare_exchange_strong(integral-type&, integral-type,
2338
+ memory_order = memory_order::seq_cst) const noexcept;
2339
+
2340
+ integral-type fetch_add(integral-type,
2341
+ memory_order = memory_order::seq_cst) const noexcept;
2342
+ integral-type fetch_sub(integral-type,
2343
+ memory_order = memory_order::seq_cst) const noexcept;
2344
+ integral-type fetch_and(integral-type,
2345
+ memory_order = memory_order::seq_cst) const noexcept;
2346
+ integral-type fetch_or(integral-type,
2347
+ memory_order = memory_order::seq_cst) const noexcept;
2348
+ integral-type fetch_xor(integral-type,
2349
+ memory_order = memory_order::seq_cst) const noexcept;
2350
+
2351
+ integral-type operator++(int) const noexcept;
2352
+ integral-type operator--(int) const noexcept;
2353
+ integral-type operator++() const noexcept;
2354
+ integral-type operator--() const noexcept;
2355
+ integral-type operator+=(integral-type) const noexcept;
2356
+ integral-type operator-=(integral-type) const noexcept;
2357
+ integral-type operator&=(integral-type) const noexcept;
2358
+ integral-type operator|=(integral-type) const noexcept;
2359
+ integral-type operator^=(integral-type) const noexcept;
2360
+
2361
+ void wait(integral-type, memory_order = memory_order::seq_cst) const noexcept;
2362
+ void notify_one() const noexcept;
2363
+ void notify_all() const noexcept;
2364
+ };
2365
+ }
2366
+ ```
2367
+
2368
+ Descriptions are provided below only for members that differ from the
2369
+ primary template.
2370
+
2371
+ The following operations perform arithmetic computations. The
2372
+ correspondence among key, operator, and computation is specified in
2373
+ [[atomic.types.int.comp]].
2374
+
2375
+ ``` cpp
2376
+ integral-type fetch_key(integral-type operand,
2377
+ memory_order order = memory_order::seq_cst) const noexcept;
2378
+ ```
2379
+
2380
+ *Effects:* Atomically replaces the value referenced by `*ptr` with the
2381
+ result of the computation applied to the value referenced by `*ptr` and
2382
+ the given operand. Memory is affected according to the value of `order`.
2383
+ These operations are atomic read-modify-write
2384
+ operations [[intro.races]].
2385
+
2386
+ *Returns:* Atomically, the value referenced by `*ptr` immediately before
2387
+ the effects.
2388
+
2389
+ *Remarks:* For signed integer types, the result is as if the object
2390
+ value and parameters were converted to their corresponding unsigned
2391
+ types, the computation performed on those types, and the result
2392
+ converted back to the signed type.
2393
+
2394
+ [*Note 1*: There are no undefined results arising from the
2395
+ computation. — *end note*]
2396
+
2397
+ ``` cpp
2398
+ integral-type operator op=(integral-type operand) const noexcept;
2399
+ ```
2400
+
2401
+ *Effects:* Equivalent to:
2402
+ `return fetch_`*`key`*`(operand) `*`op`*` operand;`
2403
+
2404
+ #### Specializations for floating-point types <a id="atomics.ref.float">[[atomics.ref.float]]</a>
2405
+
2406
+ There are specializations of the `atomic_ref` class template for all
2407
+ cv-unqualified floating-point types. For each such type
2408
+ `floating-point-type`, the specialization `atomic_ref<floating-point>`
2409
+ provides additional atomic operations appropriate to floating-point
2410
+ types.
2411
+
2412
+ ``` cpp
2413
+ namespace std {
2414
+ template<> struct atomic_ref<floating-point-type> {
2415
+ private:
2416
+ floating-point-type* ptr; // exposition only
2417
+
2418
+ public:
2419
+ using value_type = floating-point-type;
2420
+ using difference_type = value_type;
2421
+ static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
2422
+
2423
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
2424
+ bool is_lock_free() const noexcept;
2425
+
2426
+ explicit atomic_ref(floating-point-type&);
2427
+ atomic_ref(const atomic_ref&) noexcept;
2428
+ atomic_ref& operator=(const atomic_ref&) = delete;
2429
+
2430
+ void store(floating-point-type, memory_order = memory_order::seq_cst) const noexcept;
2431
+ floating-point-type operator=(floating-point-type) const noexcept;
2432
+ floating-point-type load(memory_order = memory_order::seq_cst) const noexcept;
2433
+ operator floating-point-type() const noexcept;
2434
+
2435
+ floating-point-type exchange(floating-point-type,
2436
+ memory_order = memory_order::seq_cst) const noexcept;
2437
+ bool compare_exchange_weak(floating-point-type&, floating-point-type,
2438
+ memory_order, memory_order) const noexcept;
2439
+ bool compare_exchange_strong(floating-point-type&, floating-point-type,
2440
+ memory_order, memory_order) const noexcept;
2441
+ bool compare_exchange_weak(floating-point-type&, floating-point-type,
2442
+ memory_order = memory_order::seq_cst) const noexcept;
2443
+ bool compare_exchange_strong(floating-point-type&, floating-point-type,
2444
+ memory_order = memory_order::seq_cst) const noexcept;
2445
+
2446
+ floating-point-type fetch_add(floating-point-type,
2447
+ memory_order = memory_order::seq_cst) const noexcept;
2448
+ floating-point-type fetch_sub(floating-point-type,
2449
+ memory_order = memory_order::seq_cst) const noexcept;
2450
+
2451
+ floating-point-type operator+=(floating-point-type) const noexcept;
2452
+ floating-point-type operator-=(floating-point-type) const noexcept;
2453
+
2454
+ void wait(floating-point-type, memory_order = memory_order::seq_cst) const noexcept;
2455
+ void notify_one() const noexcept;
2456
+ void notify_all() const noexcept;
2457
+ };
2458
+ }
2459
+ ```
2460
+
2461
+ Descriptions are provided below only for members that differ from the
2462
+ primary template.
2463
+
2464
+ The following operations perform arithmetic computations. The
2465
+ correspondence among key, operator, and computation is specified in
2466
+ [[atomic.types.int.comp]].
2467
+
2468
+ ``` cpp
2469
+ floating-point-type fetch_key(floating-point-type operand,
2470
+ memory_order order = memory_order::seq_cst) const noexcept;
2471
+ ```
2472
+
2473
+ *Effects:* Atomically replaces the value referenced by `*ptr` with the
2474
+ result of the computation applied to the value referenced by `*ptr` and
2475
+ the given operand. Memory is affected according to the value of `order`.
2476
+ These operations are atomic read-modify-write
2477
+ operations [[intro.races]].
2478
+
2479
+ *Returns:* Atomically, the value referenced by `*ptr` immediately before
2480
+ the effects.
2481
+
2482
+ *Remarks:* If the result is not a representable value for its
2483
+ type [[expr.pre]], the result is unspecified, but the operations
2484
+ otherwise have no undefined behavior. Atomic arithmetic operations on
2485
+ *`floating-point-type`* should conform to the
2486
+ `std::numeric_limits<`*`floating-point-type`*`>` traits associated with
2487
+ the floating-point type [[limits.syn]]. The floating-point
2488
+ environment [[cfenv]] for atomic arithmetic operations on
2489
+ *`floating-point-type`* may be different than the calling thread’s
2490
+ floating-point environment.
2491
+
2492
+ ``` cpp
2493
+ floating-point-type operator op=(floating-point-type operand) const noexcept;
2494
+ ```
2495
+
2496
+ *Effects:* Equivalent to:
2497
+ `return fetch_`*`key`*`(operand) `*`op`*` operand;`
2498
+
2499
+ #### Partial specialization for pointers <a id="atomics.ref.pointer">[[atomics.ref.pointer]]</a>
2500
+
2501
+ ``` cpp
2502
+ namespace std {
2503
+ template<class T> struct atomic_ref<T*> {
2504
+ private:
2505
+ T** ptr; // exposition only
2506
+
2507
+ public:
2508
+ using value_type = T*;
2509
+ using difference_type = ptrdiff_t;
2510
+ static constexpr size_t required_alignment = implementation-defined // required alignment for atomic_ref type's operations;
2511
+
2512
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic_ref type's operations are always lock free;
2513
+ bool is_lock_free() const noexcept;
2514
+
2515
+ explicit atomic_ref(T*&);
2516
+ atomic_ref(const atomic_ref&) noexcept;
2517
+ atomic_ref& operator=(const atomic_ref&) = delete;
2518
+
2519
+ void store(T*, memory_order = memory_order::seq_cst) const noexcept;
2520
+ T* operator=(T*) const noexcept;
2521
+ T* load(memory_order = memory_order::seq_cst) const noexcept;
2522
+ operator T*() const noexcept;
2523
+
2524
+ T* exchange(T*, memory_order = memory_order::seq_cst) const noexcept;
2525
+ bool compare_exchange_weak(T*&, T*,
2526
+ memory_order, memory_order) const noexcept;
2527
+ bool compare_exchange_strong(T*&, T*,
2528
+ memory_order, memory_order) const noexcept;
2529
+ bool compare_exchange_weak(T*&, T*,
2530
+ memory_order = memory_order::seq_cst) const noexcept;
2531
+ bool compare_exchange_strong(T*&, T*,
2532
+ memory_order = memory_order::seq_cst) const noexcept;
2533
+
2534
+ T* fetch_add(difference_type, memory_order = memory_order::seq_cst) const noexcept;
2535
+ T* fetch_sub(difference_type, memory_order = memory_order::seq_cst) const noexcept;
2536
+
2537
+ T* operator++(int) const noexcept;
2538
+ T* operator--(int) const noexcept;
2539
+ T* operator++() const noexcept;
2540
+ T* operator--() const noexcept;
2541
+ T* operator+=(difference_type) const noexcept;
2542
+ T* operator-=(difference_type) const noexcept;
2543
+
2544
+ void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
2545
+ void notify_one() const noexcept;
2546
+ void notify_all() const noexcept;
2547
+ };
2548
+ }
2549
+ ```
2550
+
2551
+ Descriptions are provided below only for members that differ from the
2552
+ primary template.
2553
+
2554
+ The following operations perform arithmetic computations. The
2555
+ correspondence among key, operator, and computation is specified in
2556
+ [[atomic.types.pointer.comp]].
2557
+
2558
+ ``` cpp
2559
+ T* fetch_key(difference_type operand, memory_order order = memory_order::seq_cst) const noexcept;
2560
+ ```
2561
+
2562
+ *Mandates:* `T` is a complete object type.
2563
+
2564
+ *Effects:* Atomically replaces the value referenced by `*ptr` with the
2565
+ result of the computation applied to the value referenced by `*ptr` and
2566
+ the given operand. Memory is affected according to the value of `order`.
2567
+ These operations are atomic read-modify-write
2568
+ operations [[intro.races]].
2569
+
2570
+ *Returns:* Atomically, the value referenced by `*ptr` immediately before
2571
+ the effects.
2572
+
2573
+ *Remarks:* The result may be an undefined address, but the operations
2574
+ otherwise have no undefined behavior.
2575
+
2576
+ ``` cpp
2577
+ T* operator op=(difference_type operand) const noexcept;
2578
+ ```
2579
+
2580
+ *Effects:* Equivalent to:
2581
+ `return fetch_`*`key`*`(operand) `*`op`*` operand;`
2582
+
2583
+ #### Member operators common to integers and pointers to objects <a id="atomics.ref.memop">[[atomics.ref.memop]]</a>
2584
+
2585
+ ``` cpp
2586
+ value_type operator++(int) const noexcept;
2587
+ ```
2588
+
2589
+ *Effects:* Equivalent to: `return fetch_add(1);`
2590
+
2591
+ ``` cpp
2592
+ value_type operator--(int) const noexcept;
2593
+ ```
2594
+
2595
+ *Effects:* Equivalent to: `return fetch_sub(1);`
2596
+
2597
+ ``` cpp
2598
+ value_type operator++() const noexcept;
2599
+ ```
2600
+
2601
+ *Effects:* Equivalent to: `return fetch_add(1) + 1;`
2602
+
2603
+ ``` cpp
2604
+ value_type operator--() const noexcept;
2605
+ ```
2606
+
2607
+ *Effects:* Equivalent to: `return fetch_sub(1) - 1;`
2608
+
2609
+ ### Class template `atomic` <a id="atomics.types.generic">[[atomics.types.generic]]</a>
2610
+
2611
+ #### General <a id="atomics.types.generic.general">[[atomics.types.generic.general]]</a>
2612
+
2613
+ ``` cpp
2614
+ namespace std {
2615
+ template<class T> struct atomic {
2616
+ using value_type = T;
2617
+
2618
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
2619
+ bool is_lock_free() const volatile noexcept;
2620
+ bool is_lock_free() const noexcept;
2621
+
2622
+ // [atomics.types.operations], operations on atomic types
2623
+ constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);
2624
+ constexpr atomic(T) noexcept;
2625
+ atomic(const atomic&) = delete;
2626
+ atomic& operator=(const atomic&) = delete;
2627
+ atomic& operator=(const atomic&) volatile = delete;
2628
+
2629
+ T load(memory_order = memory_order::seq_cst) const volatile noexcept;
2630
+ T load(memory_order = memory_order::seq_cst) const noexcept;
2631
+ operator T() const volatile noexcept;
2632
+ operator T() const noexcept;
2633
+ void store(T, memory_order = memory_order::seq_cst) volatile noexcept;
2634
+ void store(T, memory_order = memory_order::seq_cst) noexcept;
2635
+ T operator=(T) volatile noexcept;
2636
+ T operator=(T) noexcept;
2637
+
2638
+ T exchange(T, memory_order = memory_order::seq_cst) volatile noexcept;
2639
+ T exchange(T, memory_order = memory_order::seq_cst) noexcept;
2640
+ bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile noexcept;
2641
+ bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept;
2642
+ bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile noexcept;
2643
+ bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept;
2644
+ bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) volatile noexcept;
2645
+ bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) noexcept;
2646
+ bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) volatile noexcept;
2647
+ bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) noexcept;
2648
+
2649
+ void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
2650
+ void wait(T, memory_order = memory_order::seq_cst) const noexcept;
2651
+ void notify_one() volatile noexcept;
2652
+ void notify_one() noexcept;
2653
+ void notify_all() volatile noexcept;
2654
+ void notify_all() noexcept;
2655
+ };
2656
+ }
2657
+ ```
2658
+
2659
+ The template argument for `T` shall meet the *Cpp17CopyConstructible*
2660
+ and *Cpp17CopyAssignable* requirements. The program is ill-formed if any
2661
+ of
2662
+
2663
+ - `is_trivially_copyable_v<T>`,
2664
+ - `is_copy_constructible_v<T>`,
2665
+ - `is_move_constructible_v<T>`,
2666
+ - `is_copy_assignable_v<T>`, or
2667
+ - `is_move_assignable_v<T>`
2668
+
2669
+ is `false`.
2670
+
2671
+ [*Note 1*: Type arguments that are not also statically initializable
2672
+ can be difficult to use. — *end note*]
2673
+
2674
+ The specialization `atomic<bool>` is a standard-layout struct.
2675
+
2676
+ [*Note 2*: The representation of an atomic specialization need not have
2677
+ the same size and alignment requirement as its corresponding argument
2678
+ type. — *end note*]
2679
+
2680
+ #### Operations on atomic types <a id="atomics.types.operations">[[atomics.types.operations]]</a>
2681
+
2682
+ ``` cpp
2683
+ constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);
2684
+ ```
2685
+
2686
+ *Mandates:* `is_default_constructible_v<T>` is `true`.
2687
+
2688
+ *Effects:* Initializes the atomic object with the value of `T()`.
2689
+ Initialization is not an atomic operation [[intro.multithread]].
2690
+
2691
+ ``` cpp
2692
+ constexpr atomic(T desired) noexcept;
2693
+ ```
2694
+
2695
+ *Effects:* Initializes the object with the value `desired`.
2696
+ Initialization is not an atomic operation [[intro.multithread]].
2697
+
2698
+ [*Note 1*: It is possible to have an access to an atomic object `A`
2699
+ race with its construction, for example by communicating the address of
2700
+ the just-constructed object `A` to another thread via
2701
+ `memory_order::relaxed` operations on a suitable atomic pointer
2702
+ variable, and then immediately accessing `A` in the receiving thread.
2703
+ This results in undefined behavior. — *end note*]
2704
+
2705
+ ``` cpp
2706
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
2707
+ ```
2708
+
2709
+ The `static` data member `is_always_lock_free` is `true` if the atomic
2710
+ type’s operations are always lock-free, and `false` otherwise.
2711
+
2712
+ [*Note 2*: The value of `is_always_lock_free` is consistent with the
2713
+ value of the corresponding `ATOMIC_..._LOCK_FREE` macro, if
2714
+ defined. — *end note*]
2715
+
2716
+ ``` cpp
2717
+ bool is_lock_free() const volatile noexcept;
2718
+ bool is_lock_free() const noexcept;
2719
+ ```
2720
+
2721
+ *Returns:* `true` if the object’s operations are lock-free, `false`
2722
+ otherwise.
2723
+
2724
+ [*Note 3*: The return value of the `is_lock_free` member function is
2725
+ consistent with the value of `is_always_lock_free` for the same
2726
+ type. — *end note*]
2727
+
2728
+ ``` cpp
2729
+ void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
2730
+ void store(T desired, memory_order order = memory_order::seq_cst) noexcept;
2731
+ ```
2732
+
2733
+ *Constraints:* For the `volatile` overload of this function,
2734
+ `is_always_lock_free` is `true`.
2735
+
2736
+ *Preconditions:* The `order` argument is neither
2737
+ `memory_order::consume`, `memory_order::acquire`, nor
2738
+ `memory_order::acq_rel`.
2739
+
2740
+ *Effects:* Atomically replaces the value pointed to by `this` with the
2741
+ value of `desired`. Memory is affected according to the value of
2742
+ `order`.
2743
+
2744
+ ``` cpp
2745
+ T operator=(T desired) volatile noexcept;
2746
+ T operator=(T desired) noexcept;
2747
+ ```
2748
+
2749
+ *Constraints:* For the `volatile` overload of this function,
2750
+ `is_always_lock_free` is `true`.
2751
+
2752
+ *Effects:* Equivalent to `store(desired)`.
2753
+
2754
+ *Returns:* `desired`.
2755
+
2756
+ ``` cpp
2757
+ T load(memory_order order = memory_order::seq_cst) const volatile noexcept;
2758
+ T load(memory_order order = memory_order::seq_cst) const noexcept;
2759
+ ```
2760
+
2761
+ *Constraints:* For the `volatile` overload of this function,
2762
+ `is_always_lock_free` is `true`.
2763
+
2764
+ *Preconditions:* The `order` argument is neither `memory_order::release`
2765
+ nor `memory_order::acq_rel`.
2766
+
2767
+ *Effects:* Memory is affected according to the value of `order`.
2768
+
2769
+ *Returns:* Atomically returns the value pointed to by `this`.
2770
+
2771
+ ``` cpp
2772
+ operator T() const volatile noexcept;
2773
+ operator T() const noexcept;
2774
+ ```
2775
+
2776
+ *Constraints:* For the `volatile` overload of this function,
2777
+ `is_always_lock_free` is `true`.
2778
+
2779
+ *Effects:* Equivalent to: `return load();`
2780
+
2781
+ ``` cpp
2782
+ T exchange(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
2783
+ T exchange(T desired, memory_order order = memory_order::seq_cst) noexcept;
2784
+ ```
2785
+
2786
+ *Constraints:* For the `volatile` overload of this function,
2787
+ `is_always_lock_free` is `true`.
2788
+
2789
+ *Effects:* Atomically replaces the value pointed to by `this` with
2790
+ `desired`. Memory is affected according to the value of `order`. These
2791
+ operations are atomic read-modify-write
2792
+ operations [[intro.multithread]].
2793
+
2794
+ *Returns:* Atomically returns the value pointed to by `this` immediately
2795
+ before the effects.
2796
+
2797
+ ``` cpp
2798
+ bool compare_exchange_weak(T& expected, T desired,
2799
+ memory_order success, memory_order failure) volatile noexcept;
2800
+ bool compare_exchange_weak(T& expected, T desired,
2801
+ memory_order success, memory_order failure) noexcept;
2802
+ bool compare_exchange_strong(T& expected, T desired,
2803
+ memory_order success, memory_order failure) volatile noexcept;
2804
+ bool compare_exchange_strong(T& expected, T desired,
2805
+ memory_order success, memory_order failure) noexcept;
2806
+ bool compare_exchange_weak(T& expected, T desired,
2807
+ memory_order order = memory_order::seq_cst) volatile noexcept;
2808
+ bool compare_exchange_weak(T& expected, T desired,
2809
+ memory_order order = memory_order::seq_cst) noexcept;
2810
+ bool compare_exchange_strong(T& expected, T desired,
2811
+ memory_order order = memory_order::seq_cst) volatile noexcept;
2812
+ bool compare_exchange_strong(T& expected, T desired,
2813
+ memory_order order = memory_order::seq_cst) noexcept;
2814
+ ```
2815
+
2816
+ *Constraints:* For the `volatile` overload of this function,
2817
+ `is_always_lock_free` is `true`.
2818
+
2819
+ *Preconditions:* The `failure` argument is neither
2820
+ `memory_order::release` nor `memory_order::acq_rel`.
2821
+
2822
+ *Effects:* Retrieves the value in `expected`. It then atomically
2823
+ compares the value representation of the value pointed to by `this` for
2824
+ equality with that previously retrieved from `expected`, and if true,
2825
+ replaces the value pointed to by `this` with that in `desired`. If and
2826
+ only if the comparison is `true`, memory is affected according to the
2827
+ value of `success`, and if the comparison is false, memory is affected
2828
+ according to the value of `failure`. When only one `memory_order`
2829
+ argument is supplied, the value of `success` is `order`, and the value
2830
+ of `failure` is `order` except that a value of `memory_order::acq_rel`
2831
+ shall be replaced by the value `memory_order::acquire` and a value of
2832
+ `memory_order::release` shall be replaced by the value
2833
+ `memory_order::relaxed`. If and only if the comparison is false then,
2834
+ after the atomic operation, the value in `expected` is replaced by the
2835
+ value pointed to by `this` during the atomic comparison. If the
2836
+ operation returns `true`, these operations are atomic read-modify-write
2837
+ operations [[intro.multithread]] on the memory pointed to by `this`.
2838
+ Otherwise, these operations are atomic load operations on that memory.
2839
+
2840
+ *Returns:* The result of the comparison.
2841
+
2842
+ [*Note 4*:
2843
+
2844
+ For example, the effect of `compare_exchange_strong` on objects without
2845
+ padding bits [[term.padding.bits]] is
2846
+
2847
+ ``` cpp
2848
+ if (memcmp(this, &expected, sizeof(*this)) == 0)
2849
+ memcpy(this, &desired, sizeof(*this));
2850
+ else
2851
+ memcpy(&expected, this, sizeof(*this));
2852
+ ```
2853
+
2854
+ — *end note*]
2855
+
2856
+ [*Example 1*:
2857
+
2858
+ The expected use of the compare-and-exchange operations is as follows.
2859
+ The compare-and-exchange operations will update `expected` when another
2860
+ iteration of the loop is needed.
2861
+
2862
+ ``` cpp
2863
+ expected = current.load();
2864
+ do {
2865
+ desired = function(expected);
2866
+ } while (!current.compare_exchange_weak(expected, desired));
2867
+ ```
2868
+
2869
+ — *end example*]
2870
+
2871
+ [*Example 2*:
2872
+
2873
+ Because the expected value is updated only on failure, code releasing
2874
+ the memory containing the `expected` value on success will work. For
2875
+ example, list head insertion will act atomically and would not introduce
2876
+ a data race in the following code:
2877
+
2878
+ ``` cpp
2879
+ do {
2880
+ p->next = head; // make new list node point to the current head
2881
+ } while (!head.compare_exchange_weak(p->next, p)); // try to insert
2882
+ ```
2883
+
2884
+ — *end example*]
2885
+
2886
+ Implementations should ensure that weak compare-and-exchange operations
2887
+ do not consistently return `false` unless either the atomic object has
2888
+ value different from `expected` or there are concurrent modifications to
2889
+ the atomic object.
2890
+
2891
+ *Remarks:* A weak compare-and-exchange operation may fail spuriously.
2892
+ That is, even when the contents of memory referred to by `expected` and
2893
+ `this` are equal, it may return `false` and store back to `expected` the
2894
+ same memory contents that were originally there.
2895
+
2896
+ [*Note 5*: This spurious failure enables implementation of
2897
+ compare-and-exchange on a broader class of machines, e.g., load-locked
2898
+ store-conditional machines. A consequence of spurious failure is that
2899
+ nearly all uses of weak compare-and-exchange will be in a loop. When a
2900
+ compare-and-exchange is in a loop, the weak version will yield better
2901
+ performance on some platforms. When a weak compare-and-exchange would
2902
+ require a loop and a strong one would not, the strong one is
2903
+ preferable. — *end note*]
2904
+
2905
+ [*Note 6*: Under cases where the `memcpy` and `memcmp` semantics of the
2906
+ compare-and-exchange operations apply, the comparisons can fail for
2907
+ values that compare equal with `operator==` if the value representation
2908
+ has trap bits or alternate representations of the same value. Notably,
2909
+ on implementations conforming to ISO/IEC/IEEE 60559, floating-point
2910
+ `-0.0` and `+0.0` will not compare equal with `memcmp` but will compare
2911
+ equal with `operator==`, and NaNs with the same payload will compare
2912
+ equal with `memcmp` but will not compare equal with
2913
+ `operator==`. — *end note*]
2914
+
2915
+ [*Note 7*:
2916
+
2917
+ Because compare-and-exchange acts on an object’s value representation,
2918
+ padding bits that never participate in the object’s value representation
2919
+ are ignored. As a consequence, the following code is guaranteed to avoid
2920
+ spurious failure:
2921
+
2922
+ ``` cpp
2923
+ struct padded {
2924
+ char clank = 0x42;
2925
+ // Padding here.
2926
+ unsigned biff = 0xC0DEFEFE;
2927
+ };
2928
+ atomic<padded> pad = {};
2929
+
2930
+ bool zap() {
2931
+ padded expected, desired{0, 0};
2932
+ return pad.compare_exchange_strong(expected, desired);
2933
+ }
2934
+ ```
2935
+
2936
+ — *end note*]
2937
+
2938
+ [*Note 8*:
2939
+
2940
+ For a union with bits that participate in the value representation of
2941
+ some members but not others, compare-and-exchange might always fail.
2942
+ This is because such padding bits have an indeterminate value when they
2943
+ do not participate in the value representation of the active member. As
2944
+ a consequence, the following code is not guaranteed to ever succeed:
2945
+
2946
+ ``` cpp
2947
+ union pony {
2948
+ double celestia = 0.;
2949
+ short luna; // padded
2950
+ };
2951
+ atomic<pony> princesses = {};
2952
+
2953
+ bool party(pony desired) {
2954
+ pony expected;
2955
+ return princesses.compare_exchange_strong(expected, desired);
2956
+ }
2957
+ ```
2958
+
2959
+ — *end note*]
2960
+
2961
+ ``` cpp
2962
+ void wait(T old, memory_order order = memory_order::seq_cst) const volatile noexcept;
2963
+ void wait(T old, memory_order order = memory_order::seq_cst) const noexcept;
2964
+ ```
2965
+
2966
+ *Preconditions:* `order` is neither `memory_order::release` nor
2967
+ `memory_order::acq_rel`.
2968
+
2969
+ *Effects:* Repeatedly performs the following steps, in order:
2970
+
2971
+ - Evaluates `load(order)` and compares its value representation for
2972
+ equality against that of `old`.
2973
+ - If they compare unequal, returns.
2974
+ - Blocks until it is unblocked by an atomic notifying operation or is
2975
+ unblocked spuriously.
2976
+
2977
+ *Remarks:* This function is an atomic waiting
2978
+ operation [[atomics.wait]].
2979
+
2980
+ ``` cpp
2981
+ void notify_one() volatile noexcept;
2982
+ void notify_one() noexcept;
2983
+ ```
2984
+
2985
+ *Effects:* Unblocks the execution of at least one atomic waiting
2986
+ operation that is eligible to be unblocked [[atomics.wait]] by this
2987
+ call, if any such atomic waiting operations exist.
2988
+
2989
+ *Remarks:* This function is an atomic notifying
2990
+ operation [[atomics.wait]].
2991
+
2992
+ ``` cpp
2993
+ void notify_all() volatile noexcept;
2994
+ void notify_all() noexcept;
2995
+ ```
2996
+
2997
+ *Effects:* Unblocks the execution of all atomic waiting operations that
2998
+ are eligible to be unblocked [[atomics.wait]] by this call.
2999
+
3000
+ *Remarks:* This function is an atomic notifying
3001
+ operation [[atomics.wait]].
3002
+
3003
+ #### Specializations for integers <a id="atomics.types.int">[[atomics.types.int]]</a>
3004
+
3005
+ There are specializations of the `atomic` class template for the
3006
+ integral types `char`, `signed char`, `unsigned char`, `short`,
3007
+ `unsigned short`, `int`, `unsigned int`, `long`, `unsigned long`,
3008
+ `long long`, `unsigned long long`, `char8_t`, `char16_t`, `char32_t`,
3009
+ `wchar_t`, and any other types needed by the typedefs in the header
3010
+ `<cstdint>`. For each such type `integral-type`, the specialization
3011
+ `atomic<integral-type>` provides additional atomic operations
3012
+ appropriate to integral types.
3013
+
3014
+ [*Note 1*: The specialization `atomic<bool>` uses the primary template
3015
+ [[atomics.types.generic]]. — *end note*]
3016
+
3017
+ ``` cpp
3018
+ namespace std {
3019
+ template<> struct atomic<integral-type> {
3020
+ using value_type = integral-type;
3021
+ using difference_type = value_type;
3022
+
3023
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
3024
+ bool is_lock_free() const volatile noexcept;
3025
+ bool is_lock_free() const noexcept;
3026
+
3027
+ constexpr atomic() noexcept;
3028
+ constexpr atomic(integral-type) noexcept;
3029
+ atomic(const atomic&) = delete;
3030
+ atomic& operator=(const atomic&) = delete;
3031
+ atomic& operator=(const atomic&) volatile = delete;
3032
+
3033
+ void store(integral-type, memory_order = memory_order::seq_cst) volatile noexcept;
3034
+ void store(integral-type, memory_order = memory_order::seq_cst) noexcept;
3035
+ integral-type operator=(integral-type) volatile noexcept;
3036
+ integral-type operator=(integral-type) noexcept;
3037
+ integral-type load(memory_order = memory_order::seq_cst) const volatile noexcept;
3038
+ integral-type load(memory_order = memory_order::seq_cst) const noexcept;
3039
+ operator integral-type() const volatile noexcept;
3040
+ operator integral-type() const noexcept;
3041
+
3042
+ integral-type exchange(integral-type,
3043
+ memory_order = memory_order::seq_cst) volatile noexcept;
3044
+ integral-type exchange(integral-type,
3045
+ memory_order = memory_order::seq_cst) noexcept;
3046
+ bool compare_exchange_weak(integral-type&, integral-type,
3047
+ memory_order, memory_order) volatile noexcept;
3048
+ bool compare_exchange_weak(integral-type&, integral-type,
3049
+ memory_order, memory_order) noexcept;
3050
+ bool compare_exchange_strong(integral-type&, integral-type,
3051
+ memory_order, memory_order) volatile noexcept;
3052
+ bool compare_exchange_strong(integral-type&, integral-type,
3053
+ memory_order, memory_order) noexcept;
3054
+ bool compare_exchange_weak(integral-type&, integral-type,
3055
+ memory_order = memory_order::seq_cst) volatile noexcept;
3056
+ bool compare_exchange_weak(integral-type&, integral-type,
3057
+ memory_order = memory_order::seq_cst) noexcept;
3058
+ bool compare_exchange_strong(integral-type&, integral-type,
3059
+ memory_order = memory_order::seq_cst) volatile noexcept;
3060
+ bool compare_exchange_strong(integral-type&, integral-type,
3061
+ memory_order = memory_order::seq_cst) noexcept;
3062
+
3063
+ integral-type fetch_add(integral-type,
3064
+ memory_order = memory_order::seq_cst) volatile noexcept;
3065
+ integral-type fetch_add(integral-type,
3066
+ memory_order = memory_order::seq_cst) noexcept;
3067
+ integral-type fetch_sub(integral-type,
3068
+ memory_order = memory_order::seq_cst) volatile noexcept;
3069
+ integral-type fetch_sub(integral-type,
3070
+ memory_order = memory_order::seq_cst) noexcept;
3071
+ integral-type fetch_and(integral-type,
3072
+ memory_order = memory_order::seq_cst) volatile noexcept;
3073
+ integral-type fetch_and(integral-type,
3074
+ memory_order = memory_order::seq_cst) noexcept;
3075
+ integral-type fetch_or(integral-type,
3076
+ memory_order = memory_order::seq_cst) volatile noexcept;
3077
+ integral-type fetch_or(integral-type,
3078
+ memory_order = memory_order::seq_cst) noexcept;
3079
+ integral-type fetch_xor(integral-type,
3080
+ memory_order = memory_order::seq_cst) volatile noexcept;
3081
+ integral-type fetch_xor(integral-type,
3082
+ memory_order = memory_order::seq_cst) noexcept;
3083
+
3084
+ integral-type operator++(int) volatile noexcept;
3085
+ integral-type operator++(int) noexcept;
3086
+ integral-type operator--(int) volatile noexcept;
3087
+ integral-type operator--(int) noexcept;
3088
+ integral-type operator++() volatile noexcept;
3089
+ integral-type operator++() noexcept;
3090
+ integral-type operator--() volatile noexcept;
3091
+ integral-type operator--() noexcept;
3092
+ integral-type operator+=(integral-type) volatile noexcept;
3093
+ integral-type operator+=(integral-type) noexcept;
3094
+ integral-type operator-=(integral-type) volatile noexcept;
3095
+ integral-type operator-=(integral-type) noexcept;
3096
+ integral-type operator&=(integral-type) volatile noexcept;
3097
+ integral-type operator&=(integral-type) noexcept;
3098
+ integral-type operator|=(integral-type) volatile noexcept;
3099
+ integral-type operator|=(integral-type) noexcept;
3100
+ integral-type operator^=(integral-type) volatile noexcept;
3101
+ integral-type operator^=(integral-type) noexcept;
3102
+
3103
+ void wait(integral-type, memory_order = memory_order::seq_cst) const volatile noexcept;
3104
+ void wait(integral-type, memory_order = memory_order::seq_cst) const noexcept;
3105
+ void notify_one() volatile noexcept;
3106
+ void notify_one() noexcept;
3107
+ void notify_all() volatile noexcept;
3108
+ void notify_all() noexcept;
3109
+ };
3110
+ }
3111
+ ```
3112
+
3113
+ The atomic integral specializations are standard-layout structs. They
3114
+ each have a trivial destructor.
3115
+
3116
+ Descriptions are provided below only for members that differ from the
3117
+ primary template.
3118
+
3119
+ The following operations perform arithmetic computations. The
3120
+ correspondence among key, operator, and computation is specified in
3121
+ [[atomic.types.int.comp]].
3122
+
3123
+ **Table: Atomic arithmetic computations** <a id="atomic.types.int.comp">[atomic.types.int.comp]</a>
3124
+
3125
+ | | | | | | |
3126
+ | ----- | --- | -------------------- | ----- | --- | -------------------- |
3127
+ | `add` | `+` | addition | `sub` | `-` | subtraction |
3128
+ | `or` | `|` | bitwise inclusive or | `xor` | `^` | bitwise exclusive or |
3129
+ | `and` | `&` | bitwise and | | | |
3130
+
3131
+ ``` cpp
3132
+ T fetch_key(T operand, memory_order order = memory_order::seq_cst) volatile noexcept;
3133
+ T fetch_key(T operand, memory_order order = memory_order::seq_cst) noexcept;
3134
+ ```
3135
+
3136
+ *Constraints:* For the `volatile` overload of this function,
3137
+ `is_always_lock_free` is `true`.
3138
+
3139
+ *Effects:* Atomically replaces the value pointed to by `this` with the
3140
+ result of the computation applied to the value pointed to by `this` and
3141
+ the given `operand`. Memory is affected according to the value of
3142
+ `order`. These operations are atomic read-modify-write
3143
+ operations [[intro.multithread]].
3144
+
3145
+ *Returns:* Atomically, the value pointed to by `this` immediately before
3146
+ the effects.
3147
+
3148
+ *Remarks:* For signed integer types, the result is as if the object
3149
+ value and parameters were converted to their corresponding unsigned
3150
+ types, the computation performed on those types, and the result
3151
+ converted back to the signed type.
3152
+
3153
+ [*Note 1*: There are no undefined results arising from the
3154
+ computation. — *end note*]
3155
+
3156
+ ``` cpp
3157
+ T operator op=(T operand) volatile noexcept;
3158
+ T operator op=(T operand) noexcept;
3159
+ ```
3160
+
3161
+ *Constraints:* For the `volatile` overload of this function,
3162
+ `is_always_lock_free` is `true`.
3163
+
3164
+ *Effects:* Equivalent to:
3165
+ `return fetch_`*`key`*`(operand) `*`op`*` operand;`
3166
+
3167
+ #### Specializations for floating-point types <a id="atomics.types.float">[[atomics.types.float]]</a>
3168
+
3169
+ There are specializations of the `atomic` class template for all
3170
+ cv-unqualified floating-point types. For each such type
3171
+ `floating-point-type`, the specialization `atomic<floating-point-type>`
3172
+ provides additional atomic operations appropriate to floating-point
3173
+ types.
3174
+
3175
+ ``` cpp
3176
+ namespace std {
3177
+ template<> struct atomic<floating-point-type> {
3178
+ using value_type = floating-point-type;
3179
+ using difference_type = value_type;
3180
+
3181
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
3182
+ bool is_lock_free() const volatile noexcept;
3183
+ bool is_lock_free() const noexcept;
3184
+
3185
+ constexpr atomic() noexcept;
3186
+ constexpr atomic(floating-point-type) noexcept;
3187
+ atomic(const atomic&) = delete;
3188
+ atomic& operator=(const atomic&) = delete;
3189
+ atomic& operator=(const atomic&) volatile = delete;
3190
+
3191
+ void store(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept;
3192
+ void store(floating-point-type, memory_order = memory_order::seq_cst) noexcept;
3193
+ floating-point-type operator=(floating-point-type) volatile noexcept;
3194
+ floating-point-type operator=(floating-point-type) noexcept;
3195
+ floating-point-type load(memory_order = memory_order::seq_cst) volatile noexcept;
3196
+ floating-point-type load(memory_order = memory_order::seq_cst) noexcept;
3197
+ operator floating-point-type() volatile noexcept;
3198
+ operator floating-point-type() noexcept;
3199
+
3200
+ floating-point-type exchange(floating-point-type,
3201
+ memory_order = memory_order::seq_cst) volatile noexcept;
3202
+ floating-point-type exchange(floating-point-type,
3203
+ memory_order = memory_order::seq_cst) noexcept;
3204
+ bool compare_exchange_weak(floating-point-type&, floating-point-type,
3205
+ memory_order, memory_order) volatile noexcept;
3206
+ bool compare_exchange_weak(floating-point-type&, floating-point-type,
3207
+ memory_order, memory_order) noexcept;
3208
+ bool compare_exchange_strong(floating-point-type&, floating-point-type,
3209
+ memory_order, memory_order) volatile noexcept;
3210
+ bool compare_exchange_strong(floating-point-type&, floating-point-type,
3211
+ memory_order, memory_order) noexcept;
3212
+ bool compare_exchange_weak(floating-point-type&, floating-point-type,
3213
+ memory_order = memory_order::seq_cst) volatile noexcept;
3214
+ bool compare_exchange_weak(floating-point-type&, floating-point-type,
3215
+ memory_order = memory_order::seq_cst) noexcept;
3216
+ bool compare_exchange_strong(floating-point-type&, floating-point-type,
3217
+ memory_order = memory_order::seq_cst) volatile noexcept;
3218
+ bool compare_exchange_strong(floating-point-type&, floating-point-type,
3219
+ memory_order = memory_order::seq_cst) noexcept;
3220
+
3221
+ floating-point-type fetch_add(floating-point-type,
3222
+ memory_order = memory_order::seq_cst) volatile noexcept;
3223
+ floating-point-type fetch_add(floating-point-type,
3224
+ memory_order = memory_order::seq_cst) noexcept;
3225
+ floating-point-type fetch_sub(floating-point-type,
3226
+ memory_order = memory_order::seq_cst) volatile noexcept;
3227
+ floating-point-type fetch_sub(floating-point-type,
3228
+ memory_order = memory_order::seq_cst) noexcept;
3229
+
3230
+ floating-point-type operator+=(floating-point-type) volatile noexcept;
3231
+ floating-point-type operator+=(floating-point-type) noexcept;
3232
+ floating-point-type operator-=(floating-point-type) volatile noexcept;
3233
+ floating-point-type operator-=(floating-point-type) noexcept;
3234
+
3235
+ void wait(floating-point-type, memory_order = memory_order::seq_cst) const volatile noexcept;
3236
+ void wait(floating-point-type, memory_order = memory_order::seq_cst) const noexcept;
3237
+ void notify_one() volatile noexcept;
3238
+ void notify_one() noexcept;
3239
+ void notify_all() volatile noexcept;
3240
+ void notify_all() noexcept;
3241
+ };
3242
+ }
3243
+ ```
3244
+
3245
+ The atomic floating-point specializations are standard-layout structs.
3246
+ They each have a trivial destructor.
3247
+
3248
+ Descriptions are provided below only for members that differ from the
3249
+ primary template.
3250
+
3251
+ The following operations perform arithmetic addition and subtraction
3252
+ computations. The correspondence among key, operator, and computation is
3253
+ specified in [[atomic.types.int.comp]].
3254
+
3255
+ ``` cpp
3256
+ T fetch_key(T operand, memory_order order = memory_order::seq_cst) volatile noexcept;
3257
+ T fetch_key(T operand, memory_order order = memory_order::seq_cst) noexcept;
3258
+ ```
3259
+
3260
+ *Constraints:* For the `volatile` overload of this function,
3261
+ `is_always_lock_free` is `true`.
3262
+
3263
+ *Effects:* Atomically replaces the value pointed to by `this` with the
3264
+ result of the computation applied to the value pointed to by `this` and
3265
+ the given `operand`. Memory is affected according to the value of
3266
+ `order`. These operations are atomic read-modify-write
3267
+ operations [[intro.multithread]].
3268
+
3269
+ *Returns:* Atomically, the value pointed to by `this` immediately before
3270
+ the effects.
3271
+
3272
+ *Remarks:* If the result is not a representable value for its
3273
+ type [[expr.pre]] the result is unspecified, but the operations
3274
+ otherwise have no undefined behavior. Atomic arithmetic operations on
3275
+ *`floating-point-type`* should conform to the
3276
+ `std::numeric_limits<`*`floating-point-type`*`>` traits associated with
3277
+ the floating-point type [[limits.syn]]. The floating-point
3278
+ environment [[cfenv]] for atomic arithmetic operations on
3279
+ *`floating-point-type`* may be different than the calling thread’s
3280
+ floating-point environment.
3281
+
3282
+ ``` cpp
3283
+ T operator op=(T operand) volatile noexcept;
3284
+ T operator op=(T operand) noexcept;
3285
+ ```
3286
+
3287
+ *Constraints:* For the `volatile` overload of this function,
3288
+ `is_always_lock_free` is `true`.
3289
+
3290
+ *Effects:* Equivalent to:
3291
+ `return fetch_`*`key`*`(operand) `*`op`*` operand;`
3292
+
3293
+ *Remarks:* If the result is not a representable value for its
3294
+ type [[expr.pre]] the result is unspecified, but the operations
3295
+ otherwise have no undefined behavior. Atomic arithmetic operations on
3296
+ *`floating-point-type`* should conform to the
3297
+ `std::numeric_limits<`*`floating-point-type`*`>` traits associated with
3298
+ the floating-point type [[limits.syn]]. The floating-point
3299
+ environment [[cfenv]] for atomic arithmetic operations on
3300
+ *`floating-point-type`* may be different than the calling thread’s
3301
+ floating-point environment.
3302
+
3303
+ #### Partial specialization for pointers <a id="atomics.types.pointer">[[atomics.types.pointer]]</a>
3304
+
3305
+ ``` cpp
3306
+ namespace std {
3307
+ template<class T> struct atomic<T*> {
3308
+ using value_type = T*;
3309
+ using difference_type = ptrdiff_t;
3310
+
3311
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
3312
+ bool is_lock_free() const volatile noexcept;
3313
+ bool is_lock_free() const noexcept;
3314
+
3315
+ constexpr atomic() noexcept;
3316
+ constexpr atomic(T*) noexcept;
3317
+ atomic(const atomic&) = delete;
3318
+ atomic& operator=(const atomic&) = delete;
3319
+ atomic& operator=(const atomic&) volatile = delete;
3320
+
3321
+ void store(T*, memory_order = memory_order::seq_cst) volatile noexcept;
3322
+ void store(T*, memory_order = memory_order::seq_cst) noexcept;
3323
+ T* operator=(T*) volatile noexcept;
3324
+ T* operator=(T*) noexcept;
3325
+ T* load(memory_order = memory_order::seq_cst) const volatile noexcept;
3326
+ T* load(memory_order = memory_order::seq_cst) const noexcept;
3327
+ operator T*() const volatile noexcept;
3328
+ operator T*() const noexcept;
3329
+
3330
+ T* exchange(T*, memory_order = memory_order::seq_cst) volatile noexcept;
3331
+ T* exchange(T*, memory_order = memory_order::seq_cst) noexcept;
3332
+ bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept;
3333
+ bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept;
3334
+ bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept;
3335
+ bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept;
3336
+ bool compare_exchange_weak(T*&, T*,
3337
+ memory_order = memory_order::seq_cst) volatile noexcept;
3338
+ bool compare_exchange_weak(T*&, T*,
3339
+ memory_order = memory_order::seq_cst) noexcept;
3340
+ bool compare_exchange_strong(T*&, T*,
3341
+ memory_order = memory_order::seq_cst) volatile noexcept;
3342
+ bool compare_exchange_strong(T*&, T*,
3343
+ memory_order = memory_order::seq_cst) noexcept;
3344
+
3345
+ T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept;
3346
+ T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
3347
+ T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept;
3348
+ T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
3349
+
3350
+ T* operator++(int) volatile noexcept;
3351
+ T* operator++(int) noexcept;
3352
+ T* operator--(int) volatile noexcept;
3353
+ T* operator--(int) noexcept;
3354
+ T* operator++() volatile noexcept;
3355
+ T* operator++() noexcept;
3356
+ T* operator--() volatile noexcept;
3357
+ T* operator--() noexcept;
3358
+ T* operator+=(ptrdiff_t) volatile noexcept;
3359
+ T* operator+=(ptrdiff_t) noexcept;
3360
+ T* operator-=(ptrdiff_t) volatile noexcept;
3361
+ T* operator-=(ptrdiff_t) noexcept;
3362
+
3363
+ void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
3364
+ void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
3365
+ void notify_one() volatile noexcept;
3366
+ void notify_one() noexcept;
3367
+ void notify_all() volatile noexcept;
3368
+ void notify_all() noexcept;
3369
+ };
3370
+ }
3371
+ ```
3372
+
3373
+ There is a partial specialization of the `atomic` class template for
3374
+ pointers. Specializations of this partial specialization are
3375
+ standard-layout structs. They each have a trivial destructor.
3376
+
3377
+ Descriptions are provided below only for members that differ from the
3378
+ primary template.
3379
+
3380
+ The following operations perform pointer arithmetic. The correspondence
3381
+ among key, operator, and computation is specified in
3382
+ [[atomic.types.pointer.comp]].
3383
+
3384
+ **Table: Atomic pointer computations** <a id="atomic.types.pointer.comp">[atomic.types.pointer.comp]</a>
3385
+
3386
+ | | | | | | |
3387
+ | ----- | --- | -------- | ----- | --- | ----------- |
3388
+ | `add` | `+` | addition | `sub` | `-` | subtraction |
3389
+
3390
+ ``` cpp
3391
+ T* fetch_key(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept;
3392
+ T* fetch_key(ptrdiff_t operand, memory_order order = memory_order::seq_cst) noexcept;
3393
+ ```
3394
+
3395
+ *Constraints:* For the `volatile` overload of this function,
3396
+ `is_always_lock_free` is `true`.
3397
+
3398
+ *Mandates:* `T` is a complete object type.
3399
+
3400
+ [*Note 1*: Pointer arithmetic on `void*` or function pointers is
3401
+ ill-formed. — *end note*]
3402
+
3403
+ *Effects:* Atomically replaces the value pointed to by `this` with the
3404
+ result of the computation applied to the value pointed to by `this` and
3405
+ the given `operand`. Memory is affected according to the value of
3406
+ `order`. These operations are atomic read-modify-write
3407
+ operations [[intro.multithread]].
3408
+
3409
+ *Returns:* Atomically, the value pointed to by `this` immediately before
3410
+ the effects.
3411
+
3412
+ *Remarks:* The result may be an undefined address, but the operations
3413
+ otherwise have no undefined behavior.
3414
+
3415
+ ``` cpp
3416
+ T* operator op=(ptrdiff_t operand) volatile noexcept;
3417
+ T* operator op=(ptrdiff_t operand) noexcept;
3418
+ ```
3419
+
3420
+ *Constraints:* For the `volatile` overload of this function,
3421
+ `is_always_lock_free` is `true`.
3422
+
3423
+ *Effects:* Equivalent to:
3424
+ `return fetch_`*`key`*`(operand) `*`op`*` operand;`
3425
+
3426
+ #### Member operators common to integers and pointers to objects <a id="atomics.types.memop">[[atomics.types.memop]]</a>
3427
+
3428
+ ``` cpp
3429
+ value_type operator++(int) volatile noexcept;
3430
+ value_type operator++(int) noexcept;
3431
+ ```
3432
+
3433
+ *Constraints:* For the `volatile` overload of this function,
3434
+ `is_always_lock_free` is `true`.
3435
+
3436
+ *Effects:* Equivalent to: `return fetch_add(1);`
3437
+
3438
+ ``` cpp
3439
+ value_type operator--(int) volatile noexcept;
3440
+ value_type operator--(int) noexcept;
3441
+ ```
3442
+
3443
+ *Constraints:* For the `volatile` overload of this function,
3444
+ `is_always_lock_free` is `true`.
3445
+
3446
+ *Effects:* Equivalent to: `return fetch_sub(1);`
3447
+
3448
+ ``` cpp
3449
+ value_type operator++() volatile noexcept;
3450
+ value_type operator++() noexcept;
3451
+ ```
3452
+
3453
+ *Constraints:* For the `volatile` overload of this function,
3454
+ `is_always_lock_free` is `true`.
3455
+
3456
+ *Effects:* Equivalent to: `return fetch_add(1) + 1;`
3457
+
3458
+ ``` cpp
3459
+ value_type operator--() volatile noexcept;
3460
+ value_type operator--() noexcept;
3461
+ ```
3462
+
3463
+ *Constraints:* For the `volatile` overload of this function,
3464
+ `is_always_lock_free` is `true`.
3465
+
3466
+ *Effects:* Equivalent to: `return fetch_sub(1) - 1;`
3467
+
3468
+ #### Partial specializations for smart pointers <a id="util.smartptr.atomic">[[util.smartptr.atomic]]</a>
3469
+
3470
+ ##### General <a id="util.smartptr.atomic.general">[[util.smartptr.atomic.general]]</a>
3471
+
3472
+ The library provides partial specializations of the `atomic` template
3473
+ for shared-ownership smart pointers [[util.sharedptr]].
3474
+
3475
+ [*Note 1*: The partial specializations are declared in header
3476
+ `<memory>`. — *end note*]
3477
+
3478
+ The behavior of all operations is as specified in
3479
+ [[atomics.types.generic]], unless specified otherwise. The template
3480
+ parameter `T` of these partial specializations may be an incomplete
3481
+ type.
3482
+
3483
+ All changes to an atomic smart pointer in [[util.smartptr.atomic]], and
3484
+ all associated `use_count` increments, are guaranteed to be performed
3485
+ atomically. Associated `use_count` decrements are sequenced after the
3486
+ atomic operation, but are not required to be part of it. Any associated
3487
+ deletion and deallocation are sequenced after the atomic update step and
3488
+ are not part of the atomic operation.
3489
+
3490
+ [*Note 2*: If the atomic operation uses locks, locks acquired by the
3491
+ implementation will be held when any `use_count` adjustments are
3492
+ performed, and will not be held when any destruction or deallocation
3493
+ resulting from this is performed. — *end note*]
3494
+
3495
+ [*Example 1*:
3496
+
3497
+ ``` cpp
3498
+ template<typename T> class atomic_list {
3499
+ struct node {
3500
+ T t;
3501
+ shared_ptr<node> next;
3502
+ };
3503
+ atomic<shared_ptr<node>> head;
3504
+
3505
+ public:
3506
+ shared_ptr<node> find(T t) const {
3507
+ auto p = head.load();
3508
+ while (p && p->t != t)
3509
+ p = p->next;
3510
+
3511
+ return p;
3512
+ }
3513
+
3514
+ void push_front(T t) {
3515
+ auto p = make_shared<node>();
3516
+ p->t = t;
3517
+ p->next = head;
3518
+ while (!head.compare_exchange_weak(p->next, p)) {}
3519
+ }
3520
+ };
3521
+ ```
3522
+
3523
+ — *end example*]
3524
+
3525
+ ##### Partial specialization for `shared_ptr` <a id="util.smartptr.atomic.shared">[[util.smartptr.atomic.shared]]</a>
3526
+
3527
+ ``` cpp
3528
+ namespace std {
3529
+ template<class T> struct atomic<shared_ptr<T>> {
3530
+ using value_type = shared_ptr<T>;
3531
+
3532
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
3533
+ bool is_lock_free() const noexcept;
3534
+
3535
+ constexpr atomic() noexcept;
3536
+ constexpr atomic(nullptr_t) noexcept : atomic() { }
3537
+ atomic(shared_ptr<T> desired) noexcept;
3538
+ atomic(const atomic&) = delete;
3539
+ void operator=(const atomic&) = delete;
3540
+
3541
+ shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
3542
+ operator shared_ptr<T>() const noexcept;
3543
+ void store(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
3544
+ void operator=(shared_ptr<T> desired) noexcept;
3545
+
3546
+ shared_ptr<T> exchange(shared_ptr<T> desired,
3547
+ memory_order order = memory_order::seq_cst) noexcept;
3548
+ bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
3549
+ memory_order success, memory_order failure) noexcept;
3550
+ bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
3551
+ memory_order success, memory_order failure) noexcept;
3552
+ bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
3553
+ memory_order order = memory_order::seq_cst) noexcept;
3554
+ bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
3555
+ memory_order order = memory_order::seq_cst) noexcept;
3556
+
3557
+ void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
3558
+ void notify_one() noexcept;
3559
+ void notify_all() noexcept;
3560
+
3561
+ private:
3562
+ shared_ptr<T> p; // exposition only
3563
+ };
3564
+ }
3565
+ ```
3566
+
3567
+ ``` cpp
3568
+ constexpr atomic() noexcept;
3569
+ ```
3570
+
3571
+ *Effects:* Initializes `p{}`.
3572
+
3573
+ ``` cpp
3574
+ atomic(shared_ptr<T> desired) noexcept;
3575
+ ```
3576
+
3577
+ *Effects:* Initializes the object with the value `desired`.
3578
+ Initialization is not an atomic operation [[intro.multithread]].
3579
+
3580
+ [*Note 1*: It is possible to have an access to an atomic object `A`
3581
+ race with its construction, for example, by communicating the address of
3582
+ the just-constructed object `A` to another thread via
3583
+ `memory_order::relaxed` operations on a suitable atomic pointer
3584
+ variable, and then immediately accessing `A` in the receiving thread.
3585
+ This results in undefined behavior. — *end note*]
3586
+
3587
+ ``` cpp
3588
+ void store(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
3589
+ ```
3590
+
3591
+ *Preconditions:* `order` is neither `memory_order::consume`,
3592
+ `memory_order::acquire`, nor `memory_order::acq_rel`.
3593
+
3594
+ *Effects:* Atomically replaces the value pointed to by `this` with the
3595
+ value of `desired` as if by `p.swap(desired)`. Memory is affected
3596
+ according to the value of `order`.
3597
+
3598
+ ``` cpp
3599
+ void operator=(shared_ptr<T> desired) noexcept;
3600
+ ```
3601
+
3602
+ *Effects:* Equivalent to `store(desired)`.
3603
+
3604
+ ``` cpp
3605
+ shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
3606
+ ```
3607
+
3608
+ *Preconditions:* `order` is neither `memory_order::release` nor
3609
+ `memory_order::acq_rel`.
3610
+
3611
+ *Effects:* Memory is affected according to the value of `order`.
3612
+
3613
+ *Returns:* Atomically returns `p`.
3614
+
3615
+ ``` cpp
3616
+ operator shared_ptr<T>() const noexcept;
3617
+ ```
3618
+
3619
+ *Effects:* Equivalent to: `return load();`
3620
+
3621
+ ``` cpp
3622
+ shared_ptr<T> exchange(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
3623
+ ```
3624
+
3625
+ *Effects:* Atomically replaces `p` with `desired` as if by
3626
+ `p.swap(desired)`. Memory is affected according to the value of `order`.
3627
+ This is an atomic read-modify-write operation [[intro.races]].
3628
+
3629
+ *Returns:* Atomically returns the value of `p` immediately before the
3630
+ effects.
3631
+
3632
+ ``` cpp
3633
+ bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
3634
+ memory_order success, memory_order failure) noexcept;
3635
+ bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
3636
+ memory_order success, memory_order failure) noexcept;
3637
+ ```
3638
+
3639
+ *Preconditions:* `failure` is neither `memory_order::release` nor
3640
+ `memory_order::acq_rel`.
3641
+
3642
+ *Effects:* If `p` is equivalent to `expected`, assigns `desired` to `p`
3643
+ and has synchronization semantics corresponding to the value of
3644
+ `success`, otherwise assigns `p` to `expected` and has synchronization
3645
+ semantics corresponding to the value of `failure`.
3646
+
3647
+ *Returns:* `true` if `p` was equivalent to `expected`, `false`
3648
+ otherwise.
3649
+
3650
+ *Remarks:* Two `shared_ptr` objects are equivalent if they store the
3651
+ same pointer value and either share ownership or are both empty. The
3652
+ weak form may fail spuriously. See [[atomics.types.operations]].
3653
+
3654
+ If the operation returns `true`, `expected` is not accessed after the
3655
+ atomic update and the operation is an atomic read-modify-write
3656
+ operation [[intro.multithread]] on the memory pointed to by `this`.
3657
+ Otherwise, the operation is an atomic load operation on that memory, and
3658
+ `expected` is updated with the existing value read from the atomic
3659
+ object in the attempted atomic update. The `use_count` update
3660
+ corresponding to the write to `expected` is part of the atomic
3661
+ operation. The write to `expected` itself is not required to be part of
3662
+ the atomic operation.
3663
+
3664
+ ``` cpp
3665
+ bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
3666
+ memory_order order = memory_order::seq_cst) noexcept;
3667
+ ```
3668
+
3669
+ *Effects:* Equivalent to:
3670
+
3671
+ ``` cpp
3672
+ return compare_exchange_weak(expected, desired, order, fail_order);
3673
+ ```
3674
+
3675
+ where `fail_order` is the same as `order` except that a value of
3676
+ `memory_order::acq_rel` shall be replaced by the value
3677
+ `memory_order::acquire` and a value of `memory_order::release` shall be
3678
+ replaced by the value `memory_order::relaxed`.
3679
+
3680
+ ``` cpp
3681
+ bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
3682
+ memory_order order = memory_order::seq_cst) noexcept;
3683
+ ```
3684
+
3685
+ *Effects:* Equivalent to:
3686
+
3687
+ ``` cpp
3688
+ return compare_exchange_strong(expected, desired, order, fail_order);
3689
+ ```
3690
+
3691
+ where `fail_order` is the same as `order` except that a value of
3692
+ `memory_order::acq_rel` shall be replaced by the value
3693
+ `memory_order::acquire` and a value of `memory_order::release` shall be
3694
+ replaced by the value `memory_order::relaxed`.
3695
+
3696
+ ``` cpp
3697
+ void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
3698
+ ```
3699
+
3700
+ *Preconditions:* `order` is neither `memory_order::release` nor
3701
+ `memory_order::acq_rel`.
3702
+
3703
+ *Effects:* Repeatedly performs the following steps, in order:
3704
+
3705
+ - Evaluates `load(order)` and compares it to `old`.
3706
+ - If the two are not equivalent, returns.
3707
+ - Blocks until it is unblocked by an atomic notifying operation or is
3708
+ unblocked spuriously.
3709
+
3710
+ *Remarks:* Two `shared_ptr` objects are equivalent if they store the
3711
+ same pointer and either share ownership or are both empty. This function
3712
+ is an atomic waiting operation [[atomics.wait]].
3713
+
3714
+ ``` cpp
3715
+ void notify_one() noexcept;
3716
+ ```
3717
+
3718
+ *Effects:* Unblocks the execution of at least one atomic waiting
3719
+ operation that is eligible to be unblocked [[atomics.wait]] by this
3720
+ call, if any such atomic waiting operations exist.
3721
+
3722
+ *Remarks:* This function is an atomic notifying
3723
+ operation [[atomics.wait]].
3724
+
3725
+ ``` cpp
3726
+ void notify_all() noexcept;
3727
+ ```
3728
+
3729
+ *Effects:* Unblocks the execution of all atomic waiting operations that
3730
+ are eligible to be unblocked [[atomics.wait]] by this call.
3731
+
3732
+ *Remarks:* This function is an atomic notifying
3733
+ operation [[atomics.wait]].
3734
+
3735
+ ##### Partial specialization for `weak_ptr` <a id="util.smartptr.atomic.weak">[[util.smartptr.atomic.weak]]</a>
3736
+
3737
+ ``` cpp
3738
+ namespace std {
3739
+ template<class T> struct atomic<weak_ptr<T>> {
3740
+ using value_type = weak_ptr<T>;
3741
+
3742
+ static constexpr bool is_always_lock_free = implementation-defined // whether a given atomic type's operations are always lock free;
3743
+ bool is_lock_free() const noexcept;
3744
+
3745
+ constexpr atomic() noexcept;
3746
+ atomic(weak_ptr<T> desired) noexcept;
3747
+ atomic(const atomic&) = delete;
3748
+ void operator=(const atomic&) = delete;
3749
+
3750
+ weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
3751
+ operator weak_ptr<T>() const noexcept;
3752
+ void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
3753
+ void operator=(weak_ptr<T> desired) noexcept;
3754
+
3755
+ weak_ptr<T> exchange(weak_ptr<T> desired,
3756
+ memory_order order = memory_order::seq_cst) noexcept;
3757
+ bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
3758
+ memory_order success, memory_order failure) noexcept;
3759
+ bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
3760
+ memory_order success, memory_order failure) noexcept;
3761
+ bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
3762
+ memory_order order = memory_order::seq_cst) noexcept;
3763
+ bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
3764
+ memory_order order = memory_order::seq_cst) noexcept;
3765
+
3766
+ void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
3767
+ void notify_one() noexcept;
3768
+ void notify_all() noexcept;
3769
+
3770
+ private:
3771
+ weak_ptr<T> p; // exposition only
3772
+ };
3773
+ }
3774
+ ```
3775
+
3776
+ ``` cpp
3777
+ constexpr atomic() noexcept;
3778
+ ```
3779
+
3780
+ *Effects:* Initializes `p{}`.
3781
+
3782
+ ``` cpp
3783
+ atomic(weak_ptr<T> desired) noexcept;
3784
+ ```
3785
+
3786
+ *Effects:* Initializes the object with the value `desired`.
3787
+ Initialization is not an atomic operation [[intro.multithread]].
3788
+
3789
+ [*Note 2*: It is possible to have an access to an atomic object `A`
3790
+ race with its construction, for example, by communicating the address of
3791
+ the just-constructed object `A` to another thread via
3792
+ `memory_order::relaxed` operations on a suitable atomic pointer
3793
+ variable, and then immediately accessing `A` in the receiving thread.
3794
+ This results in undefined behavior. — *end note*]
3795
+
3796
+ ``` cpp
3797
+ void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
3798
+ ```
3799
+
3800
+ *Preconditions:* `order` is neither `memory_order::consume`,
3801
+ `memory_order::acquire`, nor `memory_order::acq_rel`.
3802
+
3803
+ *Effects:* Atomically replaces the value pointed to by `this` with the
3804
+ value of `desired` as if by `p.swap(desired)`. Memory is affected
3805
+ according to the value of `order`.
3806
+
3807
+ ``` cpp
3808
+ void operator=(weak_ptr<T> desired) noexcept;
3809
+ ```
3810
+
3811
+ *Effects:* Equivalent to `store(desired)`.
3812
+
3813
+ ``` cpp
3814
+ weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
3815
+ ```
3816
+
3817
+ *Preconditions:* `order` is neither `memory_order::release` nor
3818
+ `memory_order::acq_rel`.
3819
+
3820
+ *Effects:* Memory is affected according to the value of `order`.
3821
+
3822
+ *Returns:* Atomically returns `p`.
3823
+
3824
+ ``` cpp
3825
+ operator weak_ptr<T>() const noexcept;
3826
+ ```
3827
+
3828
+ *Effects:* Equivalent to: `return load();`
3829
+
3830
+ ``` cpp
3831
+ weak_ptr<T> exchange(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
3832
+ ```
3833
+
3834
+ *Effects:* Atomically replaces `p` with `desired` as if by
3835
+ `p.swap(desired)`. Memory is affected according to the value of `order`.
3836
+ This is an atomic read-modify-write operation [[intro.races]].
3837
+
3838
+ *Returns:* Atomically returns the value of `p` immediately before the
3839
+ effects.
3840
+
3841
+ ``` cpp
3842
+ bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
3843
+ memory_order success, memory_order failure) noexcept;
3844
+ bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
3845
+ memory_order success, memory_order failure) noexcept;
3846
+ ```
3847
+
3848
+ *Preconditions:* `failure` is neither `memory_order::release` nor
3849
+ `memory_order::acq_rel`.
3850
+
3851
+ *Effects:* If `p` is equivalent to `expected`, assigns `desired` to `p`
3852
+ and has synchronization semantics corresponding to the value of
3853
+ `success`, otherwise assigns `p` to `expected` and has synchronization
3854
+ semantics corresponding to the value of `failure`.
3855
+
3856
+ *Returns:* `true` if `p` was equivalent to `expected`, `false`
3857
+ otherwise.
3858
+
3859
+ *Remarks:* Two `weak_ptr` objects are equivalent if they store the same
3860
+ pointer value and either share ownership or are both empty. The weak
3861
+ form may fail spuriously. See [[atomics.types.operations]].
3862
+
3863
+ If the operation returns `true`, `expected` is not accessed after the
3864
+ atomic update and the operation is an atomic read-modify-write
3865
+ operation [[intro.multithread]] on the memory pointed to by `this`.
3866
+ Otherwise, the operation is an atomic load operation on that memory, and
3867
+ `expected` is updated with the existing value read from the atomic
3868
+ object in the attempted atomic update. The `use_count` update
3869
+ corresponding to the write to `expected` is part of the atomic
3870
+ operation. The write to `expected` itself is not required to be part of
3871
+ the atomic operation.
3872
+
3873
+ ``` cpp
3874
+ bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
3875
+ memory_order order = memory_order::seq_cst) noexcept;
3876
+ ```
3877
+
3878
+ *Effects:* Equivalent to:
3879
+
3880
+ ``` cpp
3881
+ return compare_exchange_weak(expected, desired, order, fail_order);
3882
+ ```
3883
+
3884
+ where `fail_order` is the same as `order` except that a value of
3885
+ `memory_order::acq_rel` shall be replaced by the value
3886
+ `memory_order::acquire` and a value of `memory_order::release` shall be
3887
+ replaced by the value `memory_order::relaxed`.
3888
+
3889
+ ``` cpp
3890
+ bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
3891
+ memory_order order = memory_order::seq_cst) noexcept;
3892
+ ```
3893
+
3894
+ *Effects:* Equivalent to:
3895
+
3896
+ ``` cpp
3897
+ return compare_exchange_strong(expected, desired, order, fail_order);
3898
+ ```
3899
+
3900
+ where `fail_order` is the same as `order` except that a value of
3901
+ `memory_order::acq_rel` shall be replaced by the value
3902
+ `memory_order::acquire` and a value of `memory_order::release` shall be
3903
+ replaced by the value `memory_order::relaxed`.
3904
+
3905
+ ``` cpp
3906
+ void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
3907
+ ```
3908
+
3909
+ *Preconditions:* `order` is neither `memory_order::release` nor
3910
+ `memory_order::acq_rel`.
3911
+
3912
+ *Effects:* Repeatedly performs the following steps, in order:
3913
+
3914
+ - Evaluates `load(order)` and compares it to `old`.
3915
+ - If the two are not equivalent, returns.
3916
+ - Blocks until it is unblocked by an atomic notifying operation or is
3917
+ unblocked spuriously.
3918
+
3919
+ *Remarks:* Two `weak_ptr` objects are equivalent if they store the same
3920
+ pointer and either share ownership or are both empty. This function is
3921
+ an atomic waiting operation [[atomics.wait]].
3922
+
3923
+ ``` cpp
3924
+ void notify_one() noexcept;
3925
+ ```
3926
+
3927
+ *Effects:* Unblocks the execution of at least one atomic waiting
3928
+ operation that is eligible to be unblocked [[atomics.wait]] by this
3929
+ call, if any such atomic waiting operations exist.
3930
+
3931
+ *Remarks:* This function is an atomic notifying
3932
+ operation [[atomics.wait]].
3933
+
3934
+ ``` cpp
3935
+ void notify_all() noexcept;
3936
+ ```
3937
+
3938
+ *Effects:* Unblocks the execution of all atomic waiting operations that
3939
+ are eligible to be unblocked [[atomics.wait]] by this call.
3940
+
3941
+ *Remarks:* This function is an atomic notifying
3942
+ operation [[atomics.wait]].
3943
+
3944
+ ### Non-member functions <a id="atomics.nonmembers">[[atomics.nonmembers]]</a>
3945
+
3946
+ A non-member function template whose name matches the pattern `atomic_f`
3947
+ or the pattern `atomic_f_explicit` invokes the member function `f`, with
3948
+ the value of the first parameter as the object expression and the values
3949
+ of the remaining parameters (if any) as the arguments of the member
3950
+ function call, in order. An argument for a parameter of type
3951
+ `atomic<T>::value_type*` is dereferenced when passed to the member
3952
+ function call. If no such member function exists, the program is
3953
+ ill-formed.
3954
+
3955
+ [*Note 1*: The non-member functions enable programmers to write code
3956
+ that can be compiled as either C or C++, for example in a shared header
3957
+ file. — *end note*]
3958
+
3959
+ ### Flag type and operations <a id="atomics.flag">[[atomics.flag]]</a>
3960
+
3961
+ ``` cpp
3962
+ namespace std {
3963
+ struct atomic_flag {
3964
+ constexpr atomic_flag() noexcept;
3965
+ atomic_flag(const atomic_flag&) = delete;
3966
+ atomic_flag& operator=(const atomic_flag&) = delete;
3967
+ atomic_flag& operator=(const atomic_flag&) volatile = delete;
3968
+
3969
+ bool test(memory_order = memory_order::seq_cst) const volatile noexcept;
3970
+ bool test(memory_order = memory_order::seq_cst) const noexcept;
3971
+ bool test_and_set(memory_order = memory_order::seq_cst) volatile noexcept;
3972
+ bool test_and_set(memory_order = memory_order::seq_cst) noexcept;
3973
+ void clear(memory_order = memory_order::seq_cst) volatile noexcept;
3974
+ void clear(memory_order = memory_order::seq_cst) noexcept;
3975
+
3976
+ void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
3977
+ void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
3978
+ void notify_one() volatile noexcept;
3979
+ void notify_one() noexcept;
3980
+ void notify_all() volatile noexcept;
3981
+ void notify_all() noexcept;
3982
+ };
3983
+ }
3984
+ ```
3985
+
3986
+ The `atomic_flag` type provides the classic test-and-set functionality.
3987
+ It has two states, set and clear.
3988
+
3989
+ Operations on an object of type `atomic_flag` shall be lock-free. The
3990
+ operations should also be address-free.
3991
+
3992
+ The `atomic_flag` type is a standard-layout struct. It has a trivial
3993
+ destructor.
3994
+
3995
+ ``` cpp
3996
+ constexpr atomic_flag::atomic_flag() noexcept;
3997
+ ```
3998
+
3999
+ *Effects:* Initializes `*this` to the clear state.
4000
+
4001
+ ``` cpp
4002
+ bool atomic_flag_test(const volatile atomic_flag* object) noexcept;
4003
+ bool atomic_flag_test(const atomic_flag* object) noexcept;
4004
+ bool atomic_flag_test_explicit(const volatile atomic_flag* object,
4005
+ memory_order order) noexcept;
4006
+ bool atomic_flag_test_explicit(const atomic_flag* object,
4007
+ memory_order order) noexcept;
4008
+ bool atomic_flag::test(memory_order order = memory_order::seq_cst) const volatile noexcept;
4009
+ bool atomic_flag::test(memory_order order = memory_order::seq_cst) const noexcept;
4010
+ ```
4011
+
4012
+ For `atomic_flag_test`, let `order` be `memory_order::seq_cst`.
4013
+
4014
+ *Preconditions:* `order` is neither `memory_order::release` nor
4015
+ `memory_order::acq_rel`.
4016
+
4017
+ *Effects:* Memory is affected according to the value of `order`.
4018
+
4019
+ *Returns:* Atomically returns the value pointed to by `object` or
4020
+ `this`.
4021
+
4022
+ ``` cpp
4023
+ bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept;
4024
+ bool atomic_flag_test_and_set(atomic_flag* object) noexcept;
4025
+ bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept;
4026
+ bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept;
4027
+ bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) volatile noexcept;
4028
+ bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) noexcept;
4029
+ ```
4030
+
4031
+ *Effects:* Atomically sets the value pointed to by `object` or by `this`
4032
+ to `true`. Memory is affected according to the value of `order`. These
4033
+ operations are atomic read-modify-write
4034
+ operations [[intro.multithread]].
4035
+
4036
+ *Returns:* Atomically, the value of the object immediately before the
4037
+ effects.
4038
+
4039
+ ``` cpp
4040
+ void atomic_flag_clear(volatile atomic_flag* object) noexcept;
4041
+ void atomic_flag_clear(atomic_flag* object) noexcept;
4042
+ void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept;
4043
+ void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept;
4044
+ void atomic_flag::clear(memory_order order = memory_order::seq_cst) volatile noexcept;
4045
+ void atomic_flag::clear(memory_order order = memory_order::seq_cst) noexcept;
4046
+ ```
4047
+
4048
+ *Preconditions:* The `order` argument is neither
4049
+ `memory_order::consume`, `memory_order::acquire`, nor
4050
+ `memory_order::acq_rel`.
4051
+
4052
+ *Effects:* Atomically sets the value pointed to by `object` or by `this`
4053
+ to `false`. Memory is affected according to the value of `order`.
4054
+
4055
+ ``` cpp
4056
+ void atomic_flag_wait(const volatile atomic_flag* object, bool old) noexcept;
4057
+ void atomic_flag_wait(const atomic_flag* object, bool old) noexcept;
4058
+ void atomic_flag_wait_explicit(const volatile atomic_flag* object,
4059
+ bool old, memory_order order) noexcept;
4060
+ void atomic_flag_wait_explicit(const atomic_flag* object,
4061
+ bool old, memory_order order) noexcept;
4062
+ void atomic_flag::wait(bool old, memory_order order =
4063
+ memory_order::seq_cst) const volatile noexcept;
4064
+ void atomic_flag::wait(bool old, memory_order order =
4065
+ memory_order::seq_cst) const noexcept;
4066
+ ```
4067
+
4068
+ For `atomic_flag_wait`, let `order` be `memory_order::seq_cst`. Let
4069
+ `flag` be `object` for the non-member functions and `this` for the
4070
+ member functions.
4071
+
4072
+ *Preconditions:* `order` is neither `memory_order::release` nor
4073
+ `memory_order::acq_rel`.
4074
+
4075
+ *Effects:* Repeatedly performs the following steps, in order:
4076
+
4077
+ - Evaluates `flag->test(order) != old`.
4078
+ - If the result of that evaluation is `true`, returns.
4079
+ - Blocks until it is unblocked by an atomic notifying operation or is
4080
+ unblocked spuriously.
4081
+
4082
+ *Remarks:* This function is an atomic waiting
4083
+ operation [[atomics.wait]].
4084
+
4085
+ ``` cpp
4086
+ void atomic_flag_notify_one(volatile atomic_flag* object) noexcept;
4087
+ void atomic_flag_notify_one(atomic_flag* object) noexcept;
4088
+ void atomic_flag::notify_one() volatile noexcept;
4089
+ void atomic_flag::notify_one() noexcept;
4090
+ ```
4091
+
4092
+ *Effects:* Unblocks the execution of at least one atomic waiting
4093
+ operation that is eligible to be unblocked [[atomics.wait]] by this
4094
+ call, if any such atomic waiting operations exist.
4095
+
4096
+ *Remarks:* This function is an atomic notifying
4097
+ operation [[atomics.wait]].
4098
+
4099
+ ``` cpp
4100
+ void atomic_flag_notify_all(volatile atomic_flag* object) noexcept;
4101
+ void atomic_flag_notify_all(atomic_flag* object) noexcept;
4102
+ void atomic_flag::notify_all() volatile noexcept;
4103
+ void atomic_flag::notify_all() noexcept;
4104
+ ```
4105
+
4106
+ *Effects:* Unblocks the execution of all atomic waiting operations that
4107
+ are eligible to be unblocked [[atomics.wait]] by this call.
4108
+
4109
+ *Remarks:* This function is an atomic notifying
4110
+ operation [[atomics.wait]].
4111
+
4112
+ ``` cpp
4113
+ #define ATOMIC_FLAG_INIT see below
4114
+ ```
4115
+
4116
+ *Remarks:* The macro `ATOMIC_FLAG_INIT` is defined in such a way that it
4117
+ can be used to initialize an object of type `atomic_flag` to the clear
4118
+ state. The macro can be used in the form:
4119
+
4120
+ ``` cpp
4121
+ atomic_flag guard = ATOMIC_FLAG_INIT;
4122
+ ```
4123
+
4124
+ It is unspecified whether the macro can be used in other initialization
4125
+ contexts. For a complete static-duration object, that initialization
4126
+ shall be static.
4127
+
4128
+ ### Fences <a id="atomics.fences">[[atomics.fences]]</a>
4129
+
4130
+ This subclause introduces synchronization primitives called *fences*.
4131
+ Fences can have acquire semantics, release semantics, or both. A fence
4132
+ with acquire semantics is called an *acquire fence*. A fence with
4133
+ release semantics is called a *release fence*.
4134
+
4135
+ A release fence A synchronizes with an acquire fence B if there exist
4136
+ atomic operations X and Y, both operating on some atomic object M, such
4137
+ that A is sequenced before X, X modifies M, Y is sequenced before B, and
4138
+ Y reads the value written by X or a value written by any side effect in
4139
+ the hypothetical release sequence X would head if it were a release
4140
+ operation.
4141
+
4142
+ A release fence A synchronizes with an atomic operation B that performs
4143
+ an acquire operation on an atomic object M if there exists an atomic
4144
+ operation X such that A is sequenced before X, X modifies M, and B reads
4145
+ the value written by X or a value written by any side effect in the
4146
+ hypothetical release sequence X would head if it were a release
4147
+ operation.
4148
+
4149
+ An atomic operation A that is a release operation on an atomic object M
4150
+ synchronizes with an acquire fence B if there exists some atomic
4151
+ operation X on M such that X is sequenced before B and reads the value
4152
+ written by A or a value written by any side effect in the release
4153
+ sequence headed by A.
4154
+
4155
+ ``` cpp
4156
+ extern "C" void atomic_thread_fence(memory_order order) noexcept;
4157
+ ```
4158
+
4159
+ *Effects:* Depending on the value of `order`, this operation:
4160
+
4161
+ - has no effects, if `order == memory_order::relaxed`;
4162
+ - is an acquire fence, if `order == memory_order::acquire` or
4163
+ `order == memory_order::consume`;
4164
+ - is a release fence, if `order == memory_order::release`;
4165
+ - is both an acquire fence and a release fence, if
4166
+ `order == memory_order::acq_rel`;
4167
+ - is a sequentially consistent acquire and release fence, if
4168
+ `order == memory_order::seq_cst`.
4169
+
4170
+ ``` cpp
4171
+ extern "C" void atomic_signal_fence(memory_order order) noexcept;
4172
+ ```
4173
+
4174
+ *Effects:* Equivalent to `atomic_thread_fence(order)`, except that the
4175
+ resulting ordering constraints are established only between a thread and
4176
+ a signal handler executed in the same thread.
4177
+
4178
+ [*Note 1*: `atomic_signal_fence` can be used to specify the order in
4179
+ which actions performed by the thread become visible to the signal
4180
+ handler. Compiler optimizations and reorderings of loads and stores are
4181
+ inhibited in the same way as with `atomic_thread_fence`, but the
4182
+ hardware fence instructions that `atomic_thread_fence` would have
4183
+ inserted are not emitted. — *end note*]
4184
+
4185
+ ### C compatibility <a id="stdatomic.h.syn">[[stdatomic.h.syn]]</a>
4186
+
4187
+ The header `<stdatomic.h>` provides the following definitions:
4188
+
4189
+ ``` cpp
4190
+ template<class T>
4191
+ using std-atomic = std::atomic<T>; // exposition only
4192
+
4193
+ #define _Atomic(T) std-atomic<T>
4194
+
4195
+ #define ATOMIC_BOOL_LOCK_FREE see below
4196
+ #define ATOMIC_CHAR_LOCK_FREE see below
4197
+ #define ATOMIC_CHAR16_T_LOCK_FREE see below
4198
+ #define ATOMIC_CHAR32_T_LOCK_FREE see below
4199
+ #define ATOMIC_WCHAR_T_LOCK_FREE see below
4200
+ #define ATOMIC_SHORT_LOCK_FREE see below
4201
+ #define ATOMIC_INT_LOCK_FREE see below
4202
+ #define ATOMIC_LONG_LOCK_FREE see below
4203
+ #define ATOMIC_LLONG_LOCK_FREE see below
4204
+ #define ATOMIC_POINTER_LOCK_FREE see below
4205
+
4206
+ using std::memory_order; // see below
4207
+ using std::memory_order_relaxed; // see below
4208
+ using std::memory_order_consume; // see below
4209
+ using std::memory_order_acquire; // see below
4210
+ using std::memory_order_release; // see below
4211
+ using std::memory_order_acq_rel; // see below
4212
+ using std::memory_order_seq_cst; // see below
4213
+
4214
+ using std::atomic_flag; // see below
4215
+
4216
+ using std::atomic_bool; // see below
4217
+ using std::atomic_char; // see below
4218
+ using std::atomic_schar; // see below
4219
+ using std::atomic_uchar; // see below
4220
+ using std::atomic_short; // see below
4221
+ using std::atomic_ushort; // see below
4222
+ using std::atomic_int; // see below
4223
+ using std::atomic_uint; // see below
4224
+ using std::atomic_long; // see below
4225
+ using std::atomic_ulong; // see below
4226
+ using std::atomic_llong; // see below
4227
+ using std::atomic_ullong; // see below
4228
+ using std::atomic_char8_t; // see below
4229
+ using std::atomic_char16_t; // see below
4230
+ using std::atomic_char32_t; // see below
4231
+ using std::atomic_wchar_t; // see below
4232
+ using std::atomic_int8_t; // see below
4233
+ using std::atomic_uint8_t; // see below
4234
+ using std::atomic_int16_t; // see below
4235
+ using std::atomic_uint16_t; // see below
4236
+ using std::atomic_int32_t; // see below
4237
+ using std::atomic_uint32_t; // see below
4238
+ using std::atomic_int64_t; // see below
4239
+ using std::atomic_uint64_t; // see below
4240
+ using std::atomic_int_least8_t; // see below
4241
+ using std::atomic_uint_least8_t; // see below
4242
+ using std::atomic_int_least16_t; // see below
4243
+ using std::atomic_uint_least16_t; // see below
4244
+ using std::atomic_int_least32_t; // see below
4245
+ using std::atomic_uint_least32_t; // see below
4246
+ using std::atomic_int_least64_t; // see below
4247
+ using std::atomic_uint_least64_t; // see below
4248
+ using std::atomic_int_fast8_t; // see below
4249
+ using std::atomic_uint_fast8_t; // see below
4250
+ using std::atomic_int_fast16_t; // see below
4251
+ using std::atomic_uint_fast16_t; // see below
4252
+ using std::atomic_int_fast32_t; // see below
4253
+ using std::atomic_uint_fast32_t; // see below
4254
+ using std::atomic_int_fast64_t; // see below
4255
+ using std::atomic_uint_fast64_t; // see below
4256
+ using std::atomic_intptr_t; // see below
4257
+ using std::atomic_uintptr_t; // see below
4258
+ using std::atomic_size_t; // see below
4259
+ using std::atomic_ptrdiff_t; // see below
4260
+ using std::atomic_intmax_t; // see below
4261
+ using std::atomic_uintmax_t; // see below
4262
+
4263
+ using std::atomic_is_lock_free; // see below
4264
+ using std::atomic_load; // see below
4265
+ using std::atomic_load_explicit; // see below
4266
+ using std::atomic_store; // see below
4267
+ using std::atomic_store_explicit; // see below
4268
+ using std::atomic_exchange; // see below
4269
+ using std::atomic_exchange_explicit; // see below
4270
+ using std::atomic_compare_exchange_strong; // see below
4271
+ using std::atomic_compare_exchange_strong_explicit; // see below
4272
+ using std::atomic_compare_exchange_weak; // see below
4273
+ using std::atomic_compare_exchange_weak_explicit; // see below
4274
+ using std::atomic_fetch_add; // see below
4275
+ using std::atomic_fetch_add_explicit; // see below
4276
+ using std::atomic_fetch_sub; // see below
4277
+ using std::atomic_fetch_sub_explicit; // see below
4278
+ using std::atomic_fetch_and; // see below
4279
+ using std::atomic_fetch_and_explicit; // see below
4280
+ using std::atomic_fetch_or; // see below
4281
+ using std::atomic_fetch_or_explicit; // see below
4282
+ using std::atomic_fetch_xor; // see below
4283
+ using std::atomic_fetch_xor_explicit; // see below
4284
+ using std::atomic_flag_test_and_set; // see below
4285
+ using std::atomic_flag_test_and_set_explicit; // see below
4286
+ using std::atomic_flag_clear; // see below
4287
+ using std::atomic_flag_clear_explicit; // see below
4288
+ #define ATOMIC_FLAG_INIT see below
4289
+
4290
+ using std::atomic_thread_fence; // see below
4291
+ using std::atomic_signal_fence; // see below
4292
+ ```
4293
+
4294
+ Each *using-declaration* for some name A in the synopsis above makes
4295
+ available the same entity as `std::A` declared in `<atomic>`. Each macro
4296
+ listed above other than `_Atomic(T)` is defined as in `<atomic>`. It is
4297
+ unspecified whether `<stdatomic.h>` makes available any declarations in
4298
+ namespace `std`.
4299
+
4300
+ Each of the *using-declaration*s for `intN_t`, `uintN_t`, `intptr_t`,
4301
+ and `uintptr_t` listed above is defined if and only if the
4302
+ implementation defines the corresponding *typedef-name* in
4303
+ [[atomics.syn]].
4304
+
4305
+ Neither the `_Atomic` macro, nor any of the non-macro global namespace
4306
+ declarations, are provided by any C++ standard library header other than
4307
+ `<stdatomic.h>`.
4308
+
4309
+ *Recommended practice:* Implementations should ensure that C and C++
4310
+ representations of atomic objects are compatible, so that the same
4311
+ object can be accessed as both an `_Atomic(T)` from C code and an
4312
+ `atomic<T>` from C++ code. The representations should be the same, and
4313
+ the mechanisms used to ensure atomicity and memory ordering should be
4314
+ compatible.
4315
+
4316
  ## Mutual exclusion <a id="thread.mutex">[[thread.mutex]]</a>
4317
 
4318
+ ### General <a id="thread.mutex.general">[[thread.mutex.general]]</a>
4319
+
4320
+ Subclause [[thread.mutex]] provides mechanisms for mutual exclusion:
4321
+ mutexes, locks, and call once. These mechanisms ease the production of
4322
+ race-free programs [[intro.multithread]].
4323
 
4324
  ### Header `<mutex>` synopsis <a id="mutex.syn">[[mutex.syn]]</a>
4325
 
4326
  ``` cpp
4327
  namespace std {
4328
+ // [thread.mutex.class], class mutex
4329
  class mutex;
4330
+ // [thread.mutex.recursive], class recursive_mutex
4331
  class recursive_mutex;
4332
+ // [thread.timedmutex.class] class timed_mutex
4333
  class timed_mutex;
4334
+ // [thread.timedmutex.recursive], class recursive_timed_mutex
4335
  class recursive_timed_mutex;
4336
 
4337
  struct defer_lock_t { explicit defer_lock_t() = default; };
4338
  struct try_to_lock_t { explicit try_to_lock_t() = default; };
4339
  struct adopt_lock_t { explicit adopt_lock_t() = default; };
4340
 
4341
  inline constexpr defer_lock_t defer_lock { };
4342
  inline constexpr try_to_lock_t try_to_lock { };
4343
  inline constexpr adopt_lock_t adopt_lock { };
4344
 
4345
+ // [thread.lock], locks
4346
  template<class Mutex> class lock_guard;
4347
  template<class... MutexTypes> class scoped_lock;
4348
  template<class Mutex> class unique_lock;
4349
 
4350
  template<class Mutex>
4351
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
4352
 
4353
+ // [thread.lock.algorithm], generic locking algorithms
4354
  template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
4355
  template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
4356
 
4357
  struct once_flag;
4358
 
 
4363
 
4364
  ### Header `<shared_mutex>` synopsis <a id="shared.mutex.syn">[[shared.mutex.syn]]</a>
4365
 
4366
  ``` cpp
4367
  namespace std {
4368
+ // [thread.sharedmutex.class], class shared_mutex
4369
  class shared_mutex;
4370
+ // [thread.sharedtimedmutex.class], class shared_timed_mutex
4371
  class shared_timed_mutex;
4372
+ // [thread.lock.shared], class template shared_lock
4373
  template<class Mutex> class shared_lock;
4374
  template<class Mutex>
4375
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
4376
  }
4377
  ```
 
4388
  simultaneous ownership to one or many execution agents. Both recursive
4389
  and non-recursive mutexes are supplied.
4390
 
4391
  #### Mutex types <a id="thread.mutex.requirements.mutex">[[thread.mutex.requirements.mutex]]</a>
4392
 
4393
+ ##### General <a id="thread.mutex.requirements.mutex.general">[[thread.mutex.requirements.mutex.general]]</a>
4394
+
4395
  The *mutex types* are the standard library types `mutex`,
4396
  `recursive_mutex`, `timed_mutex`, `recursive_timed_mutex`,
4397
  `shared_mutex`, and `shared_timed_mutex`. They meet the requirements set
4398
+ out in [[thread.mutex.requirements.mutex]]. In this description, `m`
4399
+ denotes an object of a mutex type.
4400
 
4401
+ [*Note 1*: The mutex types meet the *Cpp17Lockable* requirements
4402
+ [[thread.req.lockable.req]]. — *end note*]
4403
 
4404
  The mutex types meet *Cpp17DefaultConstructible* and
4405
  *Cpp17Destructible*. If initialization of an object of a mutex type
4406
  fails, an exception of type `system_error` is thrown. The mutex types
4407
  are neither copyable nor movable.
 
4419
  The implementation provides lock and unlock operations, as described
4420
  below. For purposes of determining the existence of a data race, these
4421
  behave as atomic operations [[intro.multithread]]. The lock and unlock
4422
  operations on a single mutex appears to occur in a single total order.
4423
 
4424
+ [*Note 2*: This can be viewed as the modification order
4425
  [[intro.multithread]] of the mutex. — *end note*]
4426
 
4427
+ [*Note 3*: Construction and destruction of an object of a mutex type
4428
+ need not be thread-safe; other synchronization can be used to ensure
4429
  that mutex objects are initialized and visible to other
4430
  threads. — *end note*]
4431
 
4432
  The expression `m.lock()` is well-formed and has the following
4433
  semantics:
 
4437
  the mutex.
4438
 
4439
  *Effects:* Blocks the calling thread until ownership of the mutex can be
4440
  obtained for the calling thread.
4441
 
 
 
 
 
4442
  *Synchronization:* Prior `unlock()` operations on the same object
4443
  *synchronize with*[[intro.multithread]] this operation.
4444
 
4445
+ *Ensures:* The calling thread owns the mutex.
4446
+
4447
+ *Return type:* `void`.
4448
+
4449
  *Throws:* `system_error` when an exception is
4450
  required [[thread.req.exception]].
4451
 
4452
  *Error conditions:*
4453
 
 
4473
  exchange [[atomics]]. — *end note*]
4474
 
4475
  An implementation should ensure that `try_lock()` does not consistently
4476
  return `false` in the absence of contending mutex acquisitions.
4477
 
 
 
 
 
 
4478
  *Synchronization:* If `try_lock()` returns `true`, prior `unlock()`
4479
  operations on the same object *synchronize with*[[intro.multithread]]
4480
  this operation.
4481
 
4482
  [*Note 2*: Since `lock()` does not synchronize with a failed subsequent
4483
  `try_lock()`, the visibility rules are weak enough that little would be
4484
  known about the state after a failure, even in the absence of spurious
4485
  failures. — *end note*]
4486
 
4487
+ *Return type:* `bool`.
4488
+
4489
+ *Returns:* `true` if ownership was obtained, otherwise `false`.
4490
+
4491
  *Throws:* Nothing.
4492
 
4493
  The expression `m.unlock()` is well-formed and has the following
4494
  semantics:
4495
 
 
4531
  ownership semantics. If one thread owns a mutex object, attempts by
4532
  another thread to acquire ownership of that object will fail (for
4533
  `try_lock()`) or block (for `lock()`) until the owning thread has
4534
  released ownership with a call to `unlock()`.
4535
 
4536
+ [*Note 4*: After a thread `A` has called `unlock()`, releasing a mutex,
4537
  it is possible for another thread `B` to lock the same mutex, observe
4538
  that it is no longer in use, unlock it, and destroy it, before thread
4539
  `A` appears to have returned from its unlock call. Implementations are
4540
  required to handle such scenarios correctly, as long as thread `A`
4541
  doesn’t access the mutex after the unlock call returns. These cases
 
4544
 
4545
  The class `mutex` meets all of the mutex requirements
4546
  [[thread.mutex.requirements]]. It is a standard-layout class
4547
  [[class.prop]].
4548
 
4549
+ [*Note 5*: A program can deadlock if the thread that owns a `mutex`
4550
  object calls `lock()` on that object. If the implementation can detect
4551
  the deadlock, a `resource_deadlock_would_occur` error condition might be
4552
  observed. — *end note*]
4553
 
4554
  The behavior of a program is undefined if it destroys a `mutex` object
 
4603
  - it destroys a `recursive_mutex` object owned by any thread or
4604
  - a thread terminates while owning a `recursive_mutex` object.
4605
 
4606
  #### Timed mutex types <a id="thread.timedmutex.requirements">[[thread.timedmutex.requirements]]</a>
4607
 
4608
+ ##### General <a id="thread.timedmutex.requirements.general">[[thread.timedmutex.requirements.general]]</a>
4609
+
4610
  The *timed mutex types* are the standard library types `timed_mutex`,
4611
  `recursive_timed_mutex`, and `shared_timed_mutex`. They meet the
4612
  requirements set out below. In this description, `m` denotes an object
4613
  of a mutex type, `rel_time` denotes an object of an instantiation of
4614
  `duration` [[time.duration]], and `abs_time` denotes an object of an
4615
  instantiation of `time_point` [[time.point]].
4616
 
4617
+ [*Note 1*: The timed mutex types meet the *Cpp17TimedLockable*
4618
+ requirements [[thread.req.lockable.timed]]. — *end note*]
4619
 
4620
  The expression `m.try_lock_for(rel_time)` is well-formed and has the
4621
  following semantics:
4622
 
4623
  *Preconditions:* If `m` is of type `timed_mutex` or
 
4633
 
4634
  [*Note 1*: As with `try_lock()`, there is no guarantee that ownership
4635
  will be obtained if the lock is available, but implementations are
4636
  expected to make a strong effort to do so. — *end note*]
4637
 
 
 
 
 
4638
  *Synchronization:* If `try_lock_for()` returns `true`, prior `unlock()`
4639
  operations on the same object *synchronize with*[[intro.multithread]]
4640
  this operation.
4641
 
4642
+ *Return type:* `bool`.
4643
+
4644
+ *Returns:* `true` if ownership was obtained, otherwise `false`.
4645
+
4646
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
4647
 
4648
  The expression `m.try_lock_until(abs_time)` is well-formed and has the
4649
  following semantics:
4650
 
 
4659
 
4660
  [*Note 2*: As with `try_lock()`, there is no guarantee that ownership
4661
  will be obtained if the lock is available, but implementations are
4662
  expected to make a strong effort to do so. — *end note*]
4663
 
 
 
 
 
4664
  *Synchronization:* If `try_lock_until()` returns `true`, prior
4665
  `unlock()` operations on the same object *synchronize
4666
  with*[[intro.multithread]] this operation.
4667
 
4668
+ *Return type:* `bool`.
4669
+
4670
+ *Returns:* `true` if ownership was obtained, otherwise `false`.
4671
+
4672
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
4673
 
4674
  ##### Class `timed_mutex` <a id="thread.timedmutex.class">[[thread.timedmutex.class]]</a>
4675
 
4676
  ``` cpp
 
4773
  - it destroys a `recursive_timed_mutex` object owned by any thread, or
4774
  - a thread terminates while owning a `recursive_timed_mutex` object.
4775
 
4776
  #### Shared mutex types <a id="thread.sharedmutex.requirements">[[thread.sharedmutex.requirements]]</a>
4777
 
4778
+ ##### General <a id="thread.sharedmutex.requirements.general">[[thread.sharedmutex.requirements.general]]</a>
4779
+
4780
  The standard library types `shared_mutex` and `shared_timed_mutex` are
4781
  *shared mutex types*. Shared mutex types meet the requirements of mutex
4782
  types [[thread.mutex.requirements.mutex]] and additionally meet the
4783
  requirements set out below. In this description, `m` denotes an object
4784
  of a shared mutex type.
4785
 
4786
+ [*Note 1*: The shared mutex types meet the *Cpp17SharedLockable*
4787
+ requirements [[thread.req.lockable.shared]]. — *end note*]
4788
+
4789
  In addition to the exclusive lock ownership mode specified in 
4790
  [[thread.mutex.requirements.mutex]], shared mutex types provide a
4791
  *shared lock* ownership mode. Multiple execution agents can
4792
  simultaneously hold a shared lock ownership of a shared mutex type. But
4793
  no execution agent holds a shared lock while another execution agent
 
4806
 
4807
  *Effects:* Blocks the calling thread until shared ownership of the mutex
4808
  can be obtained for the calling thread. If an exception is thrown then a
4809
  shared lock has not been acquired for the current thread.
4810
 
 
 
 
 
4811
  *Synchronization:* Prior `unlock()` operations on the same object
4812
  synchronize with [[intro.multithread]] this operation.
4813
 
4814
+ *Ensures:* The calling thread has a shared lock on the mutex.
4815
+
4816
+ *Return type:* `void`.
4817
+
4818
  *Throws:* `system_error` when an exception is
4819
  required [[thread.req.exception]].
4820
 
4821
  *Error conditions:*
4822
 
 
4850
  calling thread without blocking. If shared ownership is not obtained,
4851
  there is no effect and `try_lock_shared()` immediately returns. An
4852
  implementation may fail to obtain the lock even if it is not held by any
4853
  other thread.
4854
 
 
 
 
 
 
4855
  *Synchronization:* If `try_lock_shared()` returns `true`, prior
4856
  `unlock()` operations on the same object synchronize
4857
  with [[intro.multithread]] this operation.
4858
 
4859
+ *Return type:* `bool`.
4860
+
4861
+ *Returns:* `true` if the shared lock was acquired, otherwise `false`.
4862
+
4863
  *Throws:* Nothing.
4864
 
4865
  ##### Class `shared_mutex` <a id="thread.sharedmutex.class">[[thread.sharedmutex.class]]</a>
4866
 
4867
  ``` cpp
 
4907
 
4908
  `shared_mutex` may be a synonym for `shared_timed_mutex`.
4909
 
4910
  #### Shared timed mutex types <a id="thread.sharedtimedmutex.requirements">[[thread.sharedtimedmutex.requirements]]</a>
4911
 
4912
+ ##### General <a id="thread.sharedtimedmutex.requirements.general">[[thread.sharedtimedmutex.requirements.general]]</a>
4913
+
4914
  The standard library type `shared_timed_mutex` is a *shared timed mutex
4915
  type*. Shared timed mutex types meet the requirements of timed mutex
4916
  types [[thread.timedmutex.requirements]], shared mutex types
4917
  [[thread.sharedmutex.requirements]], and additionally meet the
4918
  requirements set out below. In this description, `m` denotes an object
4919
+ of a shared timed mutex type, `rel_time` denotes an object of an
4920
  instantiation of `duration` [[time.duration]], and `abs_time` denotes an
4921
  object of an instantiation of `time_point` [[time.point]].
4922
 
4923
+ [*Note 1*: The shared timed mutex types meet the
4924
+ *Cpp17SharedTimedLockable* requirements
4925
+ [[thread.req.lockable.shared.timed]]. — *end note*]
4926
+
4927
  The expression `m.try_lock_shared_for(rel_time)` is well-formed and has
4928
  the following semantics:
4929
 
4930
  *Preconditions:* The calling thread has no ownership of the mutex.
4931
 
 
4942
  expected to make a strong effort to do so. — *end note*]
4943
 
4944
  If an exception is thrown then a shared lock has not been acquired for
4945
  the current thread.
4946
 
 
 
 
 
4947
  *Synchronization:* If `try_lock_shared_for()` returns `true`, prior
4948
  `unlock()` operations on the same object synchronize
4949
  with [[intro.multithread]] this operation.
4950
 
4951
+ *Return type:* `bool`.
4952
+
4953
+ *Returns:* `true` if the shared lock was acquired, otherwise `false`.
4954
+
4955
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
4956
 
4957
  The expression `m.try_lock_shared_until(abs_time)` is well-formed and
4958
  has the following semantics:
4959
 
 
4971
  expected to make a strong effort to do so. — *end note*]
4972
 
4973
  If an exception is thrown then a shared lock has not been acquired for
4974
  the current thread.
4975
 
 
 
 
 
4976
  *Synchronization:* If `try_lock_shared_until()` returns `true`, prior
4977
  `unlock()` operations on the same object synchronize
4978
  with [[intro.multithread]] this operation.
4979
 
4980
+ *Return type:* `bool`.
4981
+
4982
+ *Returns:* `true` if the shared lock was acquired, otherwise `false`.
4983
+
4984
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
4985
 
4986
  ##### Class `shared_timed_mutex` <a id="thread.sharedtimedmutex.class">[[thread.sharedtimedmutex.class]]</a>
4987
 
4988
  ``` cpp
 
5031
  - a thread terminates while possessing any ownership of a
5032
  `shared_timed_mutex`.
5033
 
5034
  ### Locks <a id="thread.lock">[[thread.lock]]</a>
5035
 
5036
+ #### General <a id="thread.lock.general">[[thread.lock.general]]</a>
5037
+
5038
  A *lock* is an object that holds a reference to a lockable object and
5039
  may unlock the lockable object during the lock’s destruction (such as
5040
  when leaving block scope). An execution agent may use a lock to aid in
5041
  managing ownership of a lockable object in an exception safe manner. A
5042
  lock is said to *own* a lockable object if it is currently managing the
 
5096
 
5097
  ``` cpp
5098
  explicit lock_guard(mutex_type& m);
5099
  ```
5100
 
 
 
 
5101
  *Effects:* Initializes `pm` with `m`. Calls `m.lock()`.
5102
 
5103
  ``` cpp
5104
  lock_guard(mutex_type& m, adopt_lock_t);
5105
  ```
5106
 
5107
+ *Preconditions:* The calling thread holds a non-shared lock on `m`.
5108
 
5109
  *Effects:* Initializes `pm` with `m`.
5110
 
5111
  *Throws:* Nothing.
5112
 
5113
  ``` cpp
5114
  ~lock_guard();
5115
  ```
5116
 
5117
+ *Effects:* Equivalent to: `pm.unlock()`
5118
 
5119
  #### Class template `scoped_lock` <a id="thread.lock.scoped">[[thread.lock.scoped]]</a>
5120
 
5121
  ``` cpp
5122
  namespace std {
5123
  template<class... MutexTypes>
5124
  class scoped_lock {
5125
  public:
5126
+ using mutex_type = see below; // Only if sizeof...(MutexTypes) == 1 is true
5127
 
5128
  explicit scoped_lock(MutexTypes&... m);
5129
  explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
5130
  ~scoped_lock();
5131
 
 
5141
  An object of type `scoped_lock` controls the ownership of lockable
5142
  objects within a scope. A `scoped_lock` object maintains ownership of
5143
  lockable objects throughout the `scoped_lock` object’s lifetime
5144
  [[basic.life]]. The behavior of a program is undefined if the lockable
5145
  objects referenced by `pm` do not exist for the entire lifetime of the
5146
+ `scoped_lock` object.
5147
+
5148
+ - If `sizeof...(MutexTypes)` is one, let `Mutex` denote the sole type
5149
+ constituting the pack `MutexTypes`. `Mutex` shall meet the
5150
+ *Cpp17BasicLockable* requirements [[thread.req.lockable.basic]]. The
5151
+ member *typedef-name* `mutex_type` denotes the same type as `Mutex`.
5152
+ - Otherwise, all types in the template parameter pack `MutexTypes` shall
5153
+ meet the *Cpp17Lockable* requirements [[thread.req.lockable.req]] and
5154
+ there is no member `mutex_type`.
5155
 
5156
  ``` cpp
5157
  explicit scoped_lock(MutexTypes&... m);
5158
  ```
5159
 
 
 
 
5160
  *Effects:* Initializes `pm` with `tie(m...)`. Then if
5161
  `sizeof...(MutexTypes)` is `0`, no effects. Otherwise if
5162
  `sizeof...(MutexTypes)` is `1`, then `m.lock()`. Otherwise,
5163
  `lock(m...)`.
5164
 
5165
  ``` cpp
5166
  explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
5167
  ```
5168
 
5169
+ *Preconditions:* The calling thread holds a non-shared lock on each
5170
+ element of `m`.
5171
 
5172
  *Effects:* Initializes `pm` with `tie(m...)`.
5173
 
5174
  *Throws:* Nothing.
5175
 
 
5180
  *Effects:* For all `i` in \[`0`, `sizeof...(MutexTypes)`),
5181
  `get<i>(pm).unlock()`.
5182
 
5183
  #### Class template `unique_lock` <a id="thread.lock.unique">[[thread.lock.unique]]</a>
5184
 
5185
+ ##### General <a id="thread.lock.unique.general">[[thread.lock.unique.general]]</a>
5186
+
5187
  ``` cpp
5188
  namespace std {
5189
  template<class Mutex>
5190
  class unique_lock {
5191
  public:
 
5231
 
5232
  private:
5233
  mutex_type* pm; // exposition only
5234
  bool owns; // exposition only
5235
  };
 
 
 
5236
  }
5237
  ```
5238
 
5239
  An object of type `unique_lock` controls the ownership of a lockable
5240
  object within a scope. Ownership of the lockable object may be acquired
 
5258
 
5259
  ``` cpp
5260
  unique_lock() noexcept;
5261
  ```
5262
 
5263
+ *Ensures:* `pm == nullptr` and `owns == false`.
5264
 
5265
  ``` cpp
5266
  explicit unique_lock(mutex_type& m);
5267
  ```
5268
 
 
 
 
5269
  *Effects:* Calls `m.lock()`.
5270
 
5271
  *Ensures:* `pm == addressof(m)` and `owns == true`.
5272
 
5273
  ``` cpp
 
5279
  ``` cpp
5280
  unique_lock(mutex_type& m, try_to_lock_t);
5281
  ```
5282
 
5283
  *Preconditions:* The supplied `Mutex` type meets the *Cpp17Lockable*
5284
+ requirements [[thread.req.lockable.req]].
 
5285
 
5286
  *Effects:* Calls `m.try_lock()`.
5287
 
5288
  *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
5289
  value returned by the call to `m.try_lock()`.
5290
 
5291
  ``` cpp
5292
  unique_lock(mutex_type& m, adopt_lock_t);
5293
  ```
5294
 
5295
+ *Preconditions:* The calling thread holds a non-shared lock on `m`.
5296
 
5297
  *Ensures:* `pm == addressof(m)` and `owns == true`.
5298
 
5299
  *Throws:* Nothing.
5300
 
5301
  ``` cpp
5302
  template<class Clock, class Duration>
5303
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
5304
  ```
5305
 
5306
+ *Preconditions:* The supplied `Mutex` type meets the
 
5307
  *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
5308
 
5309
  *Effects:* Calls `m.try_lock_until(abs_time)`.
5310
 
5311
  *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
 
5314
  ``` cpp
5315
  template<class Rep, class Period>
5316
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
5317
  ```
5318
 
5319
+ *Preconditions:* The supplied `Mutex` type meets the
 
5320
  *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
5321
 
5322
  *Effects:* Calls `m.try_lock_for(rel_time)`.
5323
 
5324
  *Ensures:* `pm == addressof(m)` and `owns == res`, where `res` is the
 
5379
  *Preconditions:* The supplied `Mutex` meets the *Cpp17Lockable*
5380
  requirements [[thread.req.lockable.req]].
5381
 
5382
  *Effects:* As if by `pm->try_lock()`.
5383
 
5384
+ *Ensures:* `owns == res`, where `res` is the value returned by
5385
+ `pm->try_lock()`.
5386
 
5387
+ *Returns:* The value returned by `pm->try_lock()`.
 
5388
 
5389
  *Throws:* Any exception thrown by `pm->try_lock()`. `system_error` when
5390
  an exception is required [[thread.req.exception]].
5391
 
5392
  *Error conditions:*
 
5402
  *Preconditions:* The supplied `Mutex` type meets the
5403
  *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
5404
 
5405
  *Effects:* As if by `pm->try_lock_until(abs_time)`.
5406
 
5407
+ *Ensures:* `owns == res`, where `res` is the value returned by
5408
+ `pm->try_lock_until(abs_time)`.
5409
 
5410
+ *Returns:* The value returned by `pm->try_lock_until(abs_time)`.
 
5411
 
5412
+ *Throws:* Any exception thrown by `pm->try_lock_until(abstime)`.
5413
+ `system_error` when an exception is required [[thread.req.exception]].
5414
 
5415
  *Error conditions:*
5416
 
5417
  - `operation_not_permitted` — if `pm` is `nullptr`.
5418
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
 
5425
  *Preconditions:* The supplied `Mutex` type meets the
5426
  *Cpp17TimedLockable* requirements [[thread.req.lockable.timed]].
5427
 
5428
  *Effects:* As if by `pm->try_lock_for(rel_time)`.
5429
 
5430
+ *Ensures:* `owns == res`, where `res` is the value returned by
5431
+ `pm->try_lock_for(rel_time)`.
5432
 
5433
+ *Returns:* The value returned by `pm->try_lock_for(rel_time)`.
 
5434
 
5435
+ *Throws:* Any exception thrown by `pm->try_lock_for(rel_time)`.
5436
+ `system_error` when an exception is required [[thread.req.exception]].
5437
 
5438
  *Error conditions:*
5439
 
5440
  - `operation_not_permitted` — if `pm` is `nullptr`.
5441
  - `resource_deadlock_would_occur` — if on entry `owns` is `true`.
 
5465
 
5466
  ``` cpp
5467
  mutex_type* release() noexcept;
5468
  ```
5469
 
 
 
5470
  *Ensures:* `pm == 0` and `owns == false`.
5471
 
5472
+ *Returns:* The previous value of `pm`.
5473
+
5474
  ``` cpp
5475
  template<class Mutex>
5476
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
5477
  ```
5478
 
 
5498
 
5499
  *Returns:* `pm`.
5500
 
5501
  #### Class template `shared_lock` <a id="thread.lock.shared">[[thread.lock.shared]]</a>
5502
 
5503
+ ##### General <a id="thread.lock.shared.general">[[thread.lock.shared.general]]</a>
5504
+
5505
  ``` cpp
5506
  namespace std {
5507
  template<class Mutex>
5508
  class shared_lock {
5509
  public:
 
5547
 
5548
  private:
5549
  mutex_type* pm; // exposition only
5550
  bool owns; // exposition only
5551
  };
 
 
 
5552
  }
5553
  ```
5554
 
5555
  An object of type `shared_lock` controls the shared ownership of a
5556
  lockable object within a scope. Shared ownership of the lockable object
 
5558
  transferred, after acquisition, to another `shared_lock` object. Objects
5559
  of type `shared_lock` are not copyable but are movable. The behavior of
5560
  a program is undefined if the contained pointer `pm` is not null and the
5561
  lockable object pointed to by `pm` does not exist for the entire
5562
  remaining lifetime [[basic.life]] of the `shared_lock` object. The
5563
+ supplied `Mutex` type shall meet the *Cpp17SharedLockable* requirements
5564
+ [[thread.req.lockable.shared]].
5565
 
5566
+ [*Note 1*: `shared_lock<Mutex>` meets the *Cpp17Lockable* requirements
5567
+ [[thread.req.lockable.req]]. If `Mutex` meets the
5568
+ *Cpp17SharedTimedLockable* requirements
5569
+ [[thread.req.lockable.shared.timed]], `shared_lock<Mutex>` also meets
5570
+ the *Cpp17TimedLockable* requirements
5571
+ [[thread.req.lockable.timed]]. — *end note*]
5572
 
5573
  ##### Constructors, destructor, and assignment <a id="thread.lock.shared.cons">[[thread.lock.shared.cons]]</a>
5574
 
5575
  ``` cpp
5576
  shared_lock() noexcept;
 
5580
 
5581
  ``` cpp
5582
  explicit shared_lock(mutex_type& m);
5583
  ```
5584
 
 
 
 
5585
  *Effects:* Calls `m.lock_shared()`.
5586
 
5587
  *Ensures:* `pm == addressof(m)` and `owns == true`.
5588
 
5589
  ``` cpp
 
5594
 
5595
  ``` cpp
5596
  shared_lock(mutex_type& m, try_to_lock_t);
5597
  ```
5598
 
 
 
 
5599
  *Effects:* Calls `m.try_lock_shared()`.
5600
 
5601
  *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
5602
  value returned by the call to `m.try_lock_shared()`.
5603
 
5604
  ``` cpp
5605
  shared_lock(mutex_type& m, adopt_lock_t);
5606
  ```
5607
 
5608
+ *Preconditions:* The calling thread holds a shared lock on `m`.
5609
 
5610
  *Ensures:* `pm == addressof(m)` and `owns == true`.
5611
 
5612
  ``` cpp
5613
  template<class Clock, class Duration>
5614
  shared_lock(mutex_type& m,
5615
  const chrono::time_point<Clock, Duration>& abs_time);
5616
  ```
5617
 
5618
+ *Preconditions:* `Mutex` meets the *Cpp17SharedTimedLockable*
5619
+ requirements [[thread.req.lockable.shared.timed]].
5620
 
5621
  *Effects:* Calls `m.try_lock_shared_until(abs_time)`.
5622
 
5623
  *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
5624
  value returned by the call to `m.try_lock_shared_until(abs_time)`.
 
5627
  template<class Rep, class Period>
5628
  shared_lock(mutex_type& m,
5629
  const chrono::duration<Rep, Period>& rel_time);
5630
  ```
5631
 
5632
+ *Preconditions:* `Mutex` meets the *Cpp17SharedTimedLockable*
5633
+ requirements [[thread.req.lockable.shared.timed]].
5634
 
5635
  *Effects:* Calls `m.try_lock_shared_for(rel_time)`.
5636
 
5637
  *Ensures:* `pm == addressof(m)` and `owns == res` where `res` is the
5638
  value returned by the call to `m.try_lock_shared_for(rel_time)`.
 
5683
  bool try_lock();
5684
  ```
5685
 
5686
  *Effects:* As if by `pm->try_lock_shared()`.
5687
 
 
 
5688
  *Ensures:* `owns == res`, where `res` is the value returned by the call
5689
  to `pm->try_lock_shared()`.
5690
 
5691
+ *Returns:* The value returned by the call to `pm->try_lock_shared()`.
5692
+
5693
  *Throws:* Any exception thrown by `pm->try_lock_shared()`.
5694
  `system_error` when an exception is required [[thread.req.exception]].
5695
 
5696
  *Error conditions:*
5697
 
 
5701
  ``` cpp
5702
  template<class Clock, class Duration>
5703
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
5704
  ```
5705
 
5706
+ *Preconditions:* `Mutex` meets the *Cpp17SharedTimedLockable*
5707
+ requirements [[thread.req.lockable.shared.timed]].
5708
+
5709
  *Effects:* As if by `pm->try_lock_shared_until(abs_time)`.
5710
 
 
 
 
5711
  *Ensures:* `owns == res`, where `res` is the value returned by the call
5712
  to `pm->try_lock_shared_until(abs_time)`.
5713
 
5714
+ *Returns:* The value returned by the call to
5715
+ `pm->try_lock_shared_until(abs_time)`.
5716
+
5717
  *Throws:* Any exception thrown by `pm->try_lock_shared_until(abs_time)`.
5718
  `system_error` when an exception is required [[thread.req.exception]].
5719
 
5720
  *Error conditions:*
5721
 
 
5725
  ``` cpp
5726
  template<class Rep, class Period>
5727
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
5728
  ```
5729
 
5730
+ *Preconditions:* `Mutex` meets the *Cpp17SharedTimedLockable*
5731
+ requirements [[thread.req.lockable.shared.timed]].
5732
+
5733
  *Effects:* As if by `pm->try_lock_shared_for(rel_time)`.
5734
 
 
 
 
5735
  *Ensures:* `owns == res`, where `res` is the value returned by the call
5736
  to `pm->try_lock_shared_for(rel_time)`.
5737
 
5738
+ *Returns:* The value returned by the call to
5739
+ `pm->try_lock_shared_for(rel_time)`.
5740
+
5741
  *Throws:* Any exception thrown by `pm->try_lock_shared_for(rel_time)`.
5742
  `system_error` when an exception is required [[thread.req.exception]].
5743
 
5744
  *Error conditions:*
5745
 
 
5771
 
5772
  ``` cpp
5773
  mutex_type* release() noexcept;
5774
  ```
5775
 
 
 
5776
  *Ensures:* `pm == nullptr` and `owns == false`.
5777
 
5778
+ *Returns:* The previous value of `pm`.
5779
+
5780
  ``` cpp
5781
  template<class Mutex>
5782
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
5783
  ```
5784
 
 
5838
 
5839
  *Effects:* All arguments are locked via a sequence of calls to `lock()`,
5840
  `try_lock()`, or `unlock()` on each argument. The sequence of calls does
5841
  not result in deadlock, but is otherwise unspecified.
5842
 
5843
+ [*Note 3*: A deadlock avoidance algorithm such as try-and-back-off can
5844
  be used, but the specific algorithm is not specified to avoid
5845
  over-constraining implementations. — *end note*]
5846
 
5847
  If a call to `lock()` or `try_lock()` throws an exception, `unlock()` is
5848
  called for any argument that had been locked by a call to `lock()` or
 
5887
  *Mandates:* `is_invocable_v<Callable, Args...>` is `true`.
5888
 
5889
  *Effects:* An execution of `call_once` that does not call its `func` is
5890
  a *passive* execution. An execution of `call_once` that calls its `func`
5891
  is an *active* execution. An active execution calls *INVOKE*(
5892
+ std::forward\<Callable\>(func),
5893
+ std::forward\<Args\>(args)...) [[func.require]]. If such a call to
5894
+ `func` throws an exception the execution is *exceptional*, otherwise it
5895
+ is *returning*. An exceptional execution propagates the exception to the
5896
+ caller of `call_once`. Among all executions of `call_once` for any given
5897
+ `once_flag`: at most one is a returning execution; if there is a
5898
+ returning execution, it is the last active execution; and there are
5899
+ passive executions only if there is a returning execution.
5900
 
5901
  [*Note 1*: Passive executions allow other threads to reliably observe
5902
  the results produced by the earlier returning execution. — *end note*]
5903
 
5904
  *Synchronization:* For any given `once_flag`: all active executions
 
5942
 
5943
  — *end example*]
5944
 
5945
  ## Condition variables <a id="thread.condition">[[thread.condition]]</a>
5946
 
5947
+ ### General <a id="thread.condition.general">[[thread.condition.general]]</a>
5948
+
5949
  Condition variables provide synchronization primitives used to block a
5950
  thread until notified by some other thread that some condition is met or
5951
  until a system time is reached. Class `condition_variable` provides a
5952
  condition variable that can only wait on an object of type
5953
  `unique_lock<mutex>`, allowing the implementation to be more efficient.
 
5967
  3. the reacquisition of the lock.
5968
 
5969
  The implementation behaves as if all executions of `notify_one`,
5970
  `notify_all`, and each part of the `wait`, `wait_for`, and `wait_until`
5971
  executions are executed in a single unspecified total order consistent
5972
+ with the happens before order.
5973
 
5974
  Condition variable construction and destruction need not be
5975
  synchronized.
5976
 
5977
  ### Header `<condition_variable>` synopsis <a id="condition.variable.syn">[[condition.variable.syn]]</a>
5978
 
5979
  ``` cpp
5980
  namespace std {
5981
+ // [thread.condition.condvar], class condition_variable
5982
  class condition_variable;
5983
+ // [thread.condition.condvarany], class condition_variable_any
5984
  class condition_variable_any;
5985
 
5986
+ // [thread.condition.nonmember], non-member functions
5987
  void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
5988
 
5989
  enum class cv_status { no_timeout, timeout };
5990
  }
5991
  ```
 
6016
 
6017
  *Synchronization:* The implied `lk.unlock()` call is sequenced after the
6018
  destruction of all objects with thread storage duration associated with
6019
  the current thread.
6020
 
6021
+ [*Note 1*: The supplied lock is held until the thread exits, which
6022
+ might cause deadlock due to lock ordering issues. *end note*]
 
 
 
 
6023
 
6024
  [*Note 2*: It is the user’s responsibility to ensure that waiting
6025
  threads do not erroneously assume that the thread has finished if they
6026
  experience spurious wakeups. This typically requires that the condition
6027
  being waited for is satisfied while holding the lock on `lk`, and that
 
6085
  ~condition_variable();
6086
  ```
6087
 
6088
  *Preconditions:* There is no thread blocked on `*this`.
6089
 
6090
+ [*Note 1*: That is, all threads have been notified; they can
6091
  subsequently block on the lock specified in the wait. This relaxes the
6092
  usual rules, which would have required all wait calls to happen before
6093
  destruction. Only the notification to unblock the wait needs to happen
6094
+ before destruction. Undefined behavior ensues if a thread waits on
6095
+ `*this` once the destructor has been started, especially when the
6096
+ waiting threads are calling the wait functions in a loop or using the
6097
+ overloads of `wait`, `wait_for`, or `wait_until` that take a
6098
  predicate. — *end note*]
6099
 
6100
  ``` cpp
6101
  void notify_one() noexcept;
6102
  ```
 
6128
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock),
6129
  then returns.
6130
  - The function will unblock when signaled by a call to `notify_one()` or
6131
  a call to `notify_all()`, or spuriously.
6132
 
 
 
 
 
 
 
6133
  *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
6134
  the calling thread.
6135
 
6136
  *Throws:* Nothing.
6137
 
6138
+ *Remarks:* If the function fails to meet the postcondition,
6139
+ `terminate()` is invoked [[except.terminate]].
6140
+
6141
+ [*Note 2*: This can happen if the re-locking of the mutex throws an
6142
+ exception. — *end note*]
6143
+
6144
  ``` cpp
6145
  template<class Predicate>
6146
  void wait(unique_lock<mutex>& lock, Predicate pred);
6147
  ```
6148
 
 
6159
  ``` cpp
6160
  while (!pred())
6161
  wait(lock);
6162
  ```
6163
 
 
 
 
 
 
 
6164
  *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
6165
  the calling thread.
6166
 
6167
  *Throws:* Any exception thrown by `pred`.
6168
 
6169
+ *Remarks:* If the function fails to meet the postcondition,
6170
+ `terminate()` is invoked [[except.terminate]].
6171
+
6172
+ [*Note 3*: This can happen if the re-locking of the mutex throws an
6173
+ exception. — *end note*]
6174
+
6175
  ``` cpp
6176
  template<class Clock, class Duration>
6177
  cv_status wait_until(unique_lock<mutex>& lock,
6178
  const chrono::time_point<Clock, Duration>& abs_time);
6179
  ```
 
6195
  call to `notify_all()`, expiration of the absolute
6196
  timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
6197
  - If the function exits via an exception, `lock.lock()` is called prior
6198
  to exiting the function.
6199
 
6200
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
6201
+ the calling thread.
6202
+
6203
+ *Returns:* `cv_status::timeout` if the absolute
6204
+ timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
6205
+ `cv_status::no_timeout`.
6206
+
6207
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
6208
+
6209
  *Remarks:* If the function fails to meet the postcondition,
6210
+ `terminate()` is invoked [[except.terminate]].
6211
 
6212
  [*Note 4*: This can happen if the re-locking of the mutex throws an
6213
  exception. — *end note*]
6214
 
 
 
 
 
 
 
 
 
 
6215
  ``` cpp
6216
  template<class Rep, class Period>
6217
  cv_status wait_for(unique_lock<mutex>& lock,
6218
  const chrono::duration<Rep, Period>& rel_time);
6219
  ```
 
6230
 
6231
  ``` cpp
6232
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
6233
  ```
6234
 
6235
+ *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
6236
+ the calling thread.
6237
+
6238
  *Returns:* `cv_status::timeout` if the relative
6239
  timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
6240
  `cv_status::no_timeout`.
6241
 
6242
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
6243
+
6244
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
6245
+ is invoked [[except.terminate]].
6246
 
6247
  [*Note 5*: This can happen if the re-locking of the mutex throws an
6248
  exception. — *end note*]
6249
 
 
 
 
 
 
6250
  ``` cpp
6251
  template<class Clock, class Duration, class Predicate>
6252
  bool wait_until(unique_lock<mutex>& lock,
6253
  const chrono::time_point<Clock, Duration>& abs_time,
6254
  Predicate pred);
 
6269
  if (wait_until(lock, abs_time) == cv_status::timeout)
6270
  return pred();
6271
  return true;
6272
  ```
6273
 
 
 
 
 
 
 
6274
  *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
6275
  the calling thread.
6276
 
6277
+ [*Note 6*: The returned value indicates whether the predicate evaluated
6278
  to `true` regardless of whether the timeout was
6279
  triggered. — *end note*]
6280
 
6281
  *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
6282
  exception thrown by `pred`.
6283
 
6284
+ *Remarks:* If the function fails to meet the postcondition,
6285
+ `terminate()` is invoked [[except.terminate]].
6286
+
6287
+ [*Note 7*: This can happen if the re-locking of the mutex throws an
6288
+ exception. — *end note*]
6289
+
6290
  ``` cpp
6291
  template<class Rep, class Period, class Predicate>
6292
  bool wait_for(unique_lock<mutex>& lock,
6293
  const chrono::duration<Rep, Period>& rel_time,
6294
  Predicate pred);
 
6309
  ```
6310
 
6311
  [*Note 8*: There is no blocking if `pred()` is initially `true`, even
6312
  if the timeout has already expired. — *end note*]
6313
 
 
 
 
 
 
 
6314
  *Ensures:* `lock.owns_lock()` is `true` and `lock.mutex()` is locked by
6315
  the calling thread.
6316
 
6317
+ [*Note 9*: The returned value indicates whether the predicate evaluates
6318
+ to `true` regardless of whether the timeout was
6319
  triggered. — *end note*]
6320
 
6321
  *Throws:* Timeout-related exceptions [[thread.req.timing]] or any
6322
  exception thrown by `pred`.
6323
 
6324
+ *Remarks:* If the function fails to meet the postcondition,
6325
+ `terminate()` is invoked [[except.terminate]].
6326
+
6327
+ [*Note 10*: This can happen if the re-locking of the mutex throws an
6328
+ exception. — *end note*]
6329
+
6330
  ### Class `condition_variable_any` <a id="thread.condition.condvarany">[[thread.condition.condvarany]]</a>
6331
 
6332
+ #### General <a id="thread.condition.condvarany.general">[[thread.condition.condvarany.general]]</a>
6333
+
6334
+ In this subclause [[thread.condition.condvarany]], template arguments
6335
+ for template parameters named `Lock` shall meet the *Cpp17BasicLockable*
6336
+ requirements [[thread.req.lockable.basic]].
6337
 
6338
  [*Note 1*: All of the standard mutex types meet this requirement. If a
6339
+ type other than one of the standard mutex types or a `unique_lock`
6340
+ wrapper for a standard mutex type is used with `condition_variable_any`,
6341
+ any necessary synchronization is assumed to be in place with respect to
6342
+ the predicate associated with the `condition_variable_any`
6343
+ instance. — *end note*]
6344
 
6345
  ``` cpp
6346
  namespace std {
6347
  class condition_variable_any {
6348
  public:
 
6402
  ~condition_variable_any();
6403
  ```
6404
 
6405
  *Preconditions:* There is no thread blocked on `*this`.
6406
 
6407
+ [*Note 1*: That is, all threads have been notified; they can
6408
  subsequently block on the lock specified in the wait. This relaxes the
6409
  usual rules, which would have required all wait calls to happen before
6410
  destruction. Only the notification to unblock the wait needs to happen
6411
+ before destruction. Undefined behavior ensues if a thread waits on
6412
+ `*this` once the destructor has been started, especially when the
6413
+ waiting threads are calling the wait functions in a loop or using the
6414
+ overloads of `wait`, `wait_for`, or `wait_until` that take a
6415
  predicate. — *end note*]
6416
 
6417
  ``` cpp
6418
  void notify_one() noexcept;
6419
  ```
 
6440
  - When unblocked, calls `lock.lock()` (possibly blocking on the lock)
6441
  and returns.
6442
  - The function will unblock when signaled by a call to `notify_one()`, a
6443
  call to `notify_all()`, or spuriously.
6444
 
6445
+ *Ensures:* `lock` is locked by the calling thread.
6446
+
6447
+ *Throws:* Nothing.
6448
+
6449
  *Remarks:* If the function fails to meet the postcondition,
6450
+ `terminate()` is invoked [[except.terminate]].
6451
 
6452
  [*Note 1*: This can happen if the re-locking of the mutex throws an
6453
  exception. — *end note*]
6454
 
 
 
 
 
6455
  ``` cpp
6456
  template<class Lock, class Predicate>
6457
  void wait(Lock& lock, Predicate pred);
6458
  ```
6459
 
 
6478
  call to `notify_all()`, expiration of the absolute
6479
  timeout [[thread.req.timing]] specified by `abs_time`, or spuriously.
6480
  - If the function exits via an exception, `lock.lock()` is called prior
6481
  to exiting the function.
6482
 
 
 
 
 
 
 
6483
  *Ensures:* `lock` is locked by the calling thread.
6484
 
6485
  *Returns:* `cv_status::timeout` if the absolute
6486
  timeout [[thread.req.timing]] specified by `abs_time` expired, otherwise
6487
  `cv_status::no_timeout`.
6488
 
6489
  *Throws:* Timeout-related exceptions [[thread.req.timing]].
6490
 
6491
+ *Remarks:* If the function fails to meet the postcondition,
6492
+ `terminate()` is invoked [[except.terminate]].
6493
+
6494
+ [*Note 2*: This can happen if the re-locking of the mutex throws an
6495
+ exception. — *end note*]
6496
+
6497
  ``` cpp
6498
  template<class Lock, class Rep, class Period>
6499
  cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
6500
  ```
6501
 
 
6503
 
6504
  ``` cpp
6505
  return wait_until(lock, chrono::steady_clock::now() + rel_time);
6506
  ```
6507
 
6508
+ *Ensures:* `lock` is locked by the calling thread.
6509
+
6510
  *Returns:* `cv_status::timeout` if the relative
6511
  timeout [[thread.req.timing]] specified by `rel_time` expired, otherwise
6512
  `cv_status::no_timeout`.
6513
 
6514
+ *Throws:* Timeout-related exceptions [[thread.req.timing]].
6515
+
6516
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
6517
+ is invoked [[except.terminate]].
6518
 
6519
  [*Note 3*: This can happen if the re-locking of the mutex throws an
6520
  exception. — *end note*]
6521
 
 
 
 
 
6522
  ``` cpp
6523
  template<class Lock, class Clock, class Duration, class Predicate>
6524
  bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
6525
  ```
6526
 
 
6578
  [*Note 1*: The returned value indicates whether the predicate evaluated
6579
  to `true` regardless of whether there was a stop request. — *end note*]
6580
 
6581
  *Ensures:* `lock` is locked by the calling thread.
6582
 
6583
+ *Throws:* Any exception thrown by `pred`.
6584
+
6585
  *Remarks:* If the function fails to meet the postcondition, `terminate`
6586
  is called [[except.terminate]].
6587
 
6588
  [*Note 2*: This can happen if the re-locking of the mutex throws an
6589
  exception. — *end note*]
6590
 
 
 
6591
  ``` cpp
6592
  template<class Lock, class Clock, class Duration, class Predicate>
6593
  bool wait_until(Lock& lock, stop_token stoken,
6594
  const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
6595
  ```
 
6600
 
6601
  ``` cpp
6602
  while (!stoken.stop_requested()) {
6603
  if (pred())
6604
  return true;
6605
+ if (wait_until(lock, abs_time) == cv_status::timeout)
6606
  return pred();
6607
  }
6608
  return pred();
6609
  ```
6610
 
 
6616
  to `true` regardless of whether the timeout was triggered or a stop
6617
  request was made. — *end note*]
6618
 
6619
  *Ensures:* `lock` is locked by the calling thread.
6620
 
 
 
 
 
 
 
6621
  *Throws:* Timeout-related exceptions [[thread.req.timing]], or any
6622
  exception thrown by `pred`.
6623
 
6624
+ *Remarks:* If the function fails to meet the postcondition, `terminate`
6625
+ is called [[except.terminate]].
6626
+
6627
+ [*Note 5*: This can happen if the re-locking of the mutex throws an
6628
+ exception. — *end note*]
6629
+
6630
  ``` cpp
6631
  template<class Lock, class Rep, class Period, class Predicate>
6632
  bool wait_for(Lock& lock, stop_token stoken,
6633
  const chrono::duration<Rep, Period>& rel_time, Predicate pred);
6634
  ```
 
6640
  std::move(pred));
6641
  ```
6642
 
6643
  ## Semaphore <a id="thread.sema">[[thread.sema]]</a>
6644
 
6645
+ ### General <a id="thread.sema.general">[[thread.sema.general]]</a>
6646
+
6647
  Semaphores are lightweight synchronization primitives used to constrain
6648
  concurrent access to a shared resource. They are widely used to
6649
  implement other synchronization primitives and, whenever both are
6650
  applicable, can be more efficient than condition variables.
6651
 
 
6656
 
6657
  ### Header `<semaphore>` synopsis <a id="semaphore.syn">[[semaphore.syn]]</a>
6658
 
6659
  ``` cpp
6660
  namespace std {
6661
+ // [thread.sema.cnt], class template counting_semaphore
6662
  template<ptrdiff_t least_max_value = implementation-defined>
6663
  class counting_semaphore;
6664
 
6665
  using binary_semaphore = counting_semaphore<1>;
6666
  }
 
6668
 
6669
  ### Class template `counting_semaphore` <a id="thread.sema.cnt">[[thread.sema.cnt]]</a>
6670
 
6671
  ``` cpp
6672
  namespace std {
6673
+ template<ptrdiff_t least_max_value = implementation-defined // default value for least_max_value template parameter of counting_semaphore>
6674
  class counting_semaphore {
6675
  public:
6676
  static constexpr ptrdiff_t max() noexcept;
6677
 
6678
  constexpr explicit counting_semaphore(ptrdiff_t desired);
 
6767
  void acquire();
6768
  ```
6769
 
6770
  *Effects:* Repeatedly performs the following steps, in order:
6771
 
6772
+ - Evaluates `try_acquire()`. If the result is `true`, returns.
6773
  - Blocks on `*this` until `counter` is greater than zero.
6774
 
6775
  *Throws:* `system_error` when an exception is
6776
  required [[thread.req.exception]].
6777
 
 
6803
  *Error conditions:* Any of the error conditions allowed for mutex
6804
  types [[thread.mutex.requirements.mutex]].
6805
 
6806
  ## Coordination types <a id="thread.coord">[[thread.coord]]</a>
6807
 
6808
+ ### General <a id="thread.coord.general">[[thread.coord.general]]</a>
6809
+
6810
+ Subclause [[thread.coord]] describes various concepts related to thread
6811
  coordination, and defines the coordination types `latch` and `barrier`.
6812
  These types facilitate concurrent computation performed by a number of
6813
  threads.
6814
 
6815
  ### Latches <a id="thread.latch">[[thread.latch]]</a>
6816
 
6817
+ #### General <a id="thread.latch.general">[[thread.latch.general]]</a>
6818
+
6819
  A latch is a thread coordination mechanism that allows any number of
6820
  threads to block until an expected number of threads arrive at the latch
6821
  (via the `count_down` function). The expected count is set when the
6822
  latch is created. An individual latch is a single-use object; once the
6823
  expected count has been reached, the latch cannot be reused.
 
6930
  wait();
6931
  ```
6932
 
6933
  ### Barriers <a id="thread.barrier">[[thread.barrier]]</a>
6934
 
6935
+ #### General <a id="thread.barrier.general">[[thread.barrier.general]]</a>
6936
+
6937
  A barrier is a thread coordination mechanism whose lifetime consists of
6938
  a sequence of barrier phases, where each phase allows at most an
6939
  expected number of threads to block until the expected number of threads
6940
  arrive at the barrier.
6941
 
 
6983
 
6984
  Each *barrier phase* consists of the following steps:
6985
 
6986
  - The expected count is decremented by each call to `arrive` or
6987
  `arrive_and_drop`.
6988
+ - Exactly once after the expected count reaches zero, a thread executes
6989
+ the completion step during its call to `arrive`, `arrive_and_drop`, or
6990
+ `wait`, except that it is *implementation-defined* whether the step
6991
+ executes if no thread calls `wait`.
 
 
 
6992
  - When the completion step finishes, the expected count is reset to what
6993
  was specified by the `expected` argument to the constructor, possibly
6994
  adjusted by calls to `arrive_and_drop`, and the next phase starts.
6995
 
6996
  Each phase defines a *phase synchronization point*. Threads that arrive
 
7146
  ### Header `<future>` synopsis <a id="future.syn">[[future.syn]]</a>
7147
 
7148
  ``` cpp
7149
  namespace std {
7150
  enum class future_errc {
7151
+ broken_promise = implementation-defined // value of future_errc::broken_promise,
7152
+ future_already_retrieved = implementation-defined // value of future_errc::future_already_retrieved,
7153
+ promise_already_satisfied = implementation-defined // value of future_errc::promise_already_satisfied,
7154
+ no_state = implementation-defined // value of future_errc::no_state
7155
  };
7156
 
7157
  enum class launch : unspecified{} {
7158
  async = unspecified{},
7159
  deferred = unspecified{},
7160
+ implementation-defined // last enumerator of launch
7161
  };
7162
 
7163
  enum class future_status {
7164
  ready,
7165
  timeout,
7166
  deferred
7167
  };
7168
 
7169
+ // [futures.errors], error handling
7170
  template<> struct is_error_code_enum<future_errc> : public true_type { };
7171
  error_code make_error_code(future_errc e) noexcept;
7172
  error_condition make_error_condition(future_errc e) noexcept;
7173
 
7174
  const error_category& future_category() noexcept;
7175
 
7176
+ // [futures.future.error], class future_error
7177
  class future_error;
7178
 
7179
+ // [futures.promise], class template promise
7180
  template<class R> class promise;
7181
  template<class R> class promise<R&>;
7182
  template<> class promise<void>;
7183
 
7184
  template<class R>
7185
  void swap(promise<R>& x, promise<R>& y) noexcept;
7186
 
7187
  template<class R, class Alloc>
7188
  struct uses_allocator<promise<R>, Alloc>;
7189
 
7190
+ // [futures.unique.future], class template future
7191
  template<class R> class future;
7192
  template<class R> class future<R&>;
7193
  template<> class future<void>;
7194
 
7195
+ // [futures.shared.future], class template shared_future
7196
  template<class R> class shared_future;
7197
  template<class R> class shared_future<R&>;
7198
  template<> class shared_future<void>;
7199
 
7200
+ // [futures.task], class template packaged_task
7201
  template<class> class packaged_task; // not defined
7202
  template<class R, class... ArgTypes>
7203
  class packaged_task<R(ArgTypes...)>;
7204
 
7205
  template<class R, class... ArgTypes>
7206
  void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept;
7207
 
7208
+ // [futures.async], function template async
7209
  template<class F, class... Args>
7210
  [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
7211
  async(F&& f, Args&&... args);
7212
  template<class F, class... Args>
7213
  [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
 
7233
  ```
7234
 
7235
  *Returns:* A reference to an object of a type derived from class
7236
  `error_category`.
7237
 
7238
+ The object’s `default_error_condition` and `equivalent` virtual
7239
+ functions shall behave as specified for the class `error_category`. The
7240
+ object’s `name` virtual function returns a pointer to the string
7241
+ `"future"`.
7242
 
7243
  ``` cpp
7244
  error_code make_error_code(future_errc e) noexcept;
7245
  ```
7246
 
 
7292
  Many of the classes introduced in subclause  [[futures]] use some state
7293
  to communicate results. This *shared state* consists of some state
7294
  information and some (possibly not yet evaluated) *result*, which can be
7295
  a (possibly void) value or an exception.
7296
 
7297
+ [*Note 1*: Futures, promises, and tasks defined in this Clause
7298
  reference such shared state. — *end note*]
7299
 
7300
  [*Note 2*: The result can be any kind of object including a function to
7301
  compute that result, as used by `async` when `policy` is
7302
  `launch::deferred`. — *end note*]
 
7402
  // setting the result with deferred notification
7403
  void set_value_at_thread_exit(see below);
7404
  void set_exception_at_thread_exit(exception_ptr p);
7405
  };
7406
 
 
 
 
7407
  template<class R, class Alloc>
7408
  struct uses_allocator<promise<R>, Alloc>;
7409
  }
7410
  ```
7411
 
7412
+ For the primary template, `R` shall be an object type that meets the
7413
+ *Cpp17Destructible* requirements.
7414
+
7415
  The implementation provides the template `promise` and two
7416
  specializations, `promise<R&>` and `promise<{}void>`. These differ only
7417
  in the argument type of the member functions `set_value` and
7418
  `set_value_at_thread_exit`, as set out in their descriptions, below.
7419
 
 
7426
  template<class R, class Alloc>
7427
  struct uses_allocator<promise<R>, Alloc>
7428
  : true_type { };
7429
  ```
7430
 
7431
+ *Preconditions:* `Alloc` meets the *Cpp17Allocator*
7432
+ requirements [[allocator.requirements.general]].
7433
 
7434
  ``` cpp
7435
  promise();
7436
  template<class Allocator>
7437
  promise(allocator_arg_t, const Allocator& a);
 
7476
 
7477
  ``` cpp
7478
  future<R> get_future();
7479
  ```
7480
 
 
 
7481
  *Synchronization:* Calls to this function do not introduce data
7482
  races  [[intro.multithread]] with calls to `set_value`, `set_exception`,
7483
  `set_value_at_thread_exit`, or `set_exception_at_thread_exit`.
7484
 
7485
  [*Note 1*: Such calls need not synchronize with each
7486
  other. — *end note*]
7487
 
7488
+ *Returns:* A `future<R>` object with the same shared state as `*this`.
7489
+
7490
  *Throws:* `future_error` if `*this` has no shared state or if
7491
  `get_future` has already been called on a `promise` with the same shared
7492
  state as `*this`.
7493
 
7494
  *Error conditions:*
 
7612
  which `valid() == false` is undefined.
7613
 
7614
  [*Note 2*: It is valid to move from a future object for which
7615
  `valid() == false`. — *end note*]
7616
 
7617
+ *Recommended practice:* Implementations should detect this case and
7618
+ throw an object of type `future_error` with an error condition of
7619
+ `future_errc::no_state`.
7620
 
7621
  ``` cpp
7622
  namespace std {
7623
  template<class R>
7624
  class future {
 
7644
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
7645
  };
7646
  }
7647
  ```
7648
 
7649
+ For the primary template, `R` shall be an object type that meets the
7650
+ *Cpp17Destructible* requirements.
7651
+
7652
  The implementation provides the template `future` and two
7653
  specializations, `future<R&>` and `future<{}void>`. These differ only in
7654
  the return type and return value of the member function `get`, as set
7655
  out in its description, below.
7656
 
 
7686
 
7687
  ``` cpp
7688
  future& operator=(future&& rhs) noexcept;
7689
  ```
7690
 
7691
+ *Effects:* If `addressof(rhs) == this` is `true`, there are no effects.
7692
+ Otherwise:
7693
 
7694
  - Releases any shared state [[futures.state]].
7695
  - move assigns the contents of `rhs` to `*this`.
7696
 
7697
  *Ensures:*
7698
 
7699
  - `valid()` returns the same value as `rhs.valid()` prior to the
7700
  assignment.
7701
+ - If `addressof(rhs) == this` is `false`, `rhs.valid() == false`.
7702
 
7703
  ``` cpp
7704
  shared_future<R> share() noexcept;
7705
  ```
7706
 
7707
+ *Ensures:* `valid() == false`.
7708
+
7709
  *Returns:* `shared_future<R>(std::move(*this))`.
7710
 
 
 
7711
  ``` cpp
7712
  R future::get();
7713
  R& future<R&>::get();
7714
  void future<void>::get();
7715
  ```
 
7722
 
7723
  - `wait()`s until the shared state is ready, then retrieves the value
7724
  stored in the shared state;
7725
  - releases any shared state [[futures.state]].
7726
 
7727
+ *Ensures:* `valid() == false`.
7728
+
7729
  *Returns:*
7730
 
7731
  - `future::get()` returns the value `v` stored in the object’s shared
7732
  state as `std::move(v)`.
7733
  - `future<R&>::get()` returns the reference stored as value in the
 
7735
  - `future<void>::get()` returns nothing.
7736
 
7737
  *Throws:* The stored exception, if an exception was stored in the shared
7738
  state.
7739
 
 
 
7740
  ``` cpp
7741
  bool valid() const noexcept;
7742
  ```
7743
 
7744
  *Returns:* `true` only if `*this` refers to a shared state.
 
7811
  a `shared_future` object for which `valid() == false` is undefined.
7812
 
7813
  [*Note 2*: It is valid to copy or move from a `shared_future` object
7814
  for which `valid()` is `false`. — *end note*]
7815
 
7816
+ *Recommended practice:* Implementations should detect this case and
7817
+ throw an object of type `future_error` with an error condition of
7818
+ `future_errc::no_state`.
7819
 
7820
  ``` cpp
7821
  namespace std {
7822
  template<class R>
7823
  class shared_future {
 
7843
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
7844
  };
7845
  }
7846
  ```
7847
 
7848
+ For the primary template, `R` shall be an object type that meets the
7849
+ *Cpp17Destructible* requirements.
7850
+
7851
  The implementation provides the template `shared_future` and two
7852
  specializations, `shared_future<R&>` and `shared_future<void>`. These
7853
  differ only in the return type and return value of the member function
7854
  `get`, as set out in its description, below.
7855
 
 
7894
 
7895
  ``` cpp
7896
  shared_future& operator=(shared_future&& rhs) noexcept;
7897
  ```
7898
 
7899
+ *Effects:* If `addressof(rhs) == this` is `true`, there are no effects.
7900
+ Otherwise:
7901
 
7902
  - Releases any shared state [[futures.state]];
7903
  - move assigns the contents of `rhs` to `*this`.
7904
 
7905
  *Ensures:*
7906
 
7907
  - `valid()` returns the same value as `rhs.valid()` returned prior to
7908
  the assignment.
7909
+ - If `addressof(rhs) == this` is `false`, `rhs.valid() == false`.
7910
 
7911
  ``` cpp
7912
  shared_future& operator=(const shared_future& rhs) noexcept;
7913
  ```
7914
 
7915
+ *Effects:* If `addressof(rhs) == this` is `true`, there are no effects.
7916
+ Otherwise:
7917
 
7918
  - Releases any shared state [[futures.state]];
7919
+ - assigns the contents of `rhs` to `*this`. \[*Note 3*: As a result,
7920
  `*this` refers to the same shared state as `rhs` (if
7921
  any). — *end note*]
7922
 
7923
  *Ensures:* `valid() == rhs.valid()`.
7924
 
 
7931
  [*Note 1*: As described above, the template and its two required
7932
  specializations differ only in the return type and return value of the
7933
  member function `get`. — *end note*]
7934
 
7935
  [*Note 2*: Access to a value object stored in the shared state is
7936
+ unsynchronized, so operations on `R` might introduce a data
7937
+ race [[intro.multithread]]. — *end note*]
7938
 
7939
  *Effects:* `wait()`s until the shared state is ready, then retrieves the
7940
  value stored in the shared state.
7941
 
7942
  *Returns:*
7943
 
7944
  - `shared_future::get()` returns a const reference to the value stored
7945
+ in the object’s shared state. \[*Note 4*: Access through that
7946
  reference after the shared state has been destroyed produces undefined
7947
  behavior; this can be avoided by not storing the reference in any
7948
  storage with a greater lifetime than the `shared_future` object that
7949
  returned the reference. — *end note*]
7950
  - `shared_future<R&>::get()` returns the reference stored as value in
 
8024
  ```
8025
 
8026
  *Mandates:* The following are all `true`:
8027
 
8028
  - `is_constructible_v<decay_t<F>, F>`,
8029
+ - `(is_constructible_v<decay_t<Args>, Args> && ...)`, and
 
 
8030
  - `is_invocable_v<decay_t<F>, decay_t<Args>...>`.
8031
 
 
 
 
8032
  *Effects:* The first function behaves the same as a call to the second
8033
  function with a `policy` argument of `launch::async | launch::deferred`
8034
  and the same arguments for `F` and `Args`. The second function creates a
8035
  shared state that is associated with the returned `future` object. The
8036
  further behavior of the second function depends on the `policy` argument
8037
  as follows (if more than one of these conditions applies, the
8038
  implementation may choose any of the corresponding policies):
8039
 
8040
  - If `launch::async` is set in `policy`, calls
8041
+ `invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)`
8042
+ [[func.invoke]], [[thread.thread.constr]] as if in a new thread of
8043
+ execution represented by a `thread` object with the values produced by
8044
+ `auto` being materialized [[conv.rval]] in the thread that called
8045
+ `async`. Any return value is stored as the result in the shared state.
8046
+ Any exception propagated from the execution of
8047
+ `invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)`
 
8048
  is stored as the exceptional result in the shared state. The `thread`
8049
  object is stored in the shared state and affects the behavior of any
8050
  asynchronous return objects that reference that state.
8051
  - If `launch::deferred` is set in `policy`, stores
8052
+ `auto(std::forward<F>(f))` and `auto(std::forward<Args>(args))...` in
8053
+ the shared state. These copies of `f` and `args` constitute a
8054
+ *deferred function*. Invocation of the deferred function evaluates
 
8055
  `invoke(std::move(g), std::move(xyz))` where `g` is the stored value
8056
+ of `auto(std::forward<F>(f))` and `xyz` is the stored copy of
8057
+ `auto(std::forward<Args>(args))...`. Any return value is stored as the
8058
+ result in the shared state. Any exception propagated from the
8059
+ execution of the deferred function is stored as the exceptional result
8060
+ in the shared state. The shared state is not made ready until the
8061
+ function has completed. The first call to a non-timed waiting
8062
+ function [[futures.state]] on an asynchronous return object referring
8063
+ to this shared state invokes the deferred function in the thread that
8064
+ called the waiting function. Once evaluation of
8065
  `invoke(std::move(g), std::move(xyz))` begins, the function is no
8066
+ longer considered deferred. *Recommended practice:* If this policy is
8067
+ specified together with other policies, such as when using a `policy`
8068
+ value of `launch::async | launch::deferred`, implementations should
8069
+ defer invocation or the selection of the policy when no more
8070
+ concurrency can be effectively exploited.
8071
  - If no value is set in the launch policy, or a value is set that is
8072
  neither specified in this document nor by the implementation, the
8073
  behavior is undefined.
8074
 
8075
+ *Synchronization:* The invocation of `async` synchronizes with the
8076
+ invocation of `f`. The completion of the function `f` is sequenced
8077
+ before the shared state is made ready.
8078
 
8079
+ [*Note 1*: These apply regardless of the provided `policy` argument,
8080
+ and even if the corresponding `future` object is moved to another
8081
+ thread. However, it is possible for `f` not to be called at all, in
8082
+ which case its completion never happens. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
8083
 
8084
  If the implementation chooses the `launch::async` policy,
8085
 
8086
  - a call to a waiting function on an asynchronous return object that
8087
  shares the shared state created by this `async` call shall block until
 
8091
  with [[intro.multithread]] the return from the first function that
8092
  successfully detects the ready status of the shared state or with the
8093
  return from the last function that releases the shared state,
8094
  whichever happens first.
8095
 
8096
+ *Returns:* An object of type
8097
+ `future<invoke_result_t<decay_t<F>, decay_t<Args>...>>` that refers to
8098
+ the shared state created by this call to `async`.
8099
+
8100
+ [*Note 2*: If a future obtained from `async` is moved outside the local
8101
+ scope, the future’s destructor can block for the shared state to become
8102
+ ready. — *end note*]
8103
+
8104
  *Throws:* `system_error` if `policy == launch::async` and the
8105
  implementation is unable to start a new thread, or `std::bad_alloc` if
8106
+ memory for the internal data structures cannot be allocated.
8107
 
8108
  *Error conditions:*
8109
 
8110
  - `resource_unavailable_try_again` — if `policy == launch::async` and
8111
  the system is unable to start a new thread.
8112
 
8113
+ [*Note 1*: Line \#1 might not result in concurrency because the `async`
8114
+ call uses the default policy, which might use `launch::deferred`, in
8115
+ which case the lambda might not be invoked until the `get()` call; in
8116
+ that case, `work1` and `work2` are called on the same thread and there
8117
+ is no concurrency. — *end note*]
8118
 
8119
  ### Class template `packaged_task` <a id="futures.task">[[futures.task]]</a>
8120
 
8121
+ #### General <a id="futures.task.general">[[futures.task.general]]</a>
8122
+
8123
  The class template `packaged_task` defines a type for wrapping a
8124
  function or callable object so that the return value of the function or
8125
  callable object is stored in a future when it is invoked.
8126
 
8127
  When the `packaged_task` object is invoked, its stored task is invoked
 
8162
 
8163
  void reset();
8164
  };
8165
 
8166
  template<class R, class... ArgTypes>
8167
+ packaged_task(R (*)(ArgTypes...)) -> packaged_task<R(ArgTypes...)>;
8168
+
8169
+ template<class F> packaged_task(F) -> packaged_task<see below>;
8170
  }
8171
  ```
8172
 
8173
  #### Member functions <a id="futures.task.members">[[futures.task.members]]</a>
8174
 
 
8178
 
8179
  *Effects:* The object has no shared state and no stored task.
8180
 
8181
  ``` cpp
8182
  template<class F>
8183
+ explicit packaged_task(F&& f);
8184
  ```
8185
 
8186
  *Constraints:* `remove_cvref_t<F>` is not the same type as
8187
  `packaged_task<R(ArgTypes...)>`.
8188
 
 
8193
 
8194
  *Effects:* Constructs a new `packaged_task` object with a shared state
8195
  and initializes the object’s stored task with `std::forward<F>(f)`.
8196
 
8197
  *Throws:* Any exceptions thrown by the copy or move constructor of `f`,
8198
+ or `bad_alloc` if memory for the internal data structures cannot be
8199
  allocated.
8200
 
8201
+ ``` cpp
8202
+ template<class F> packaged_task(F) -> packaged_task<see below>;
8203
+ ```
8204
+
8205
+ *Constraints:* `&F::operator()` is well-formed when treated as an
8206
+ unevaluated operand [[term.unevaluated.operand]] and either
8207
+
8208
+ - `F::operator()` is a non-static member function and
8209
+ `decltype(&F::operator())` is either of the form
8210
+ `R(G::*)(A...)` cv \\ₒₚₜ ` `noexceptₒₚₜ or of the form
8211
+ `R(*)(G, A...) `noexceptₒₚₜ for a type `G`, or
8212
+ - `F::operator()` is a static member function and
8213
+ `decltype(&F::operator())` is of the form `R(*)(A...) `noexceptₒₚₜ .
8214
+
8215
+ *Remarks:* The deduced type is `packaged_task<R(A...)>`.
8216
+
8217
  ``` cpp
8218
  packaged_task(packaged_task&& rhs) noexcept;
8219
  ```
8220
 
8221
  *Effects:* Transfers ownership of `rhs`’s shared state to `*this`,
 
8258
 
8259
  ``` cpp
8260
  future<R> get_future();
8261
  ```
8262
 
 
 
 
8263
  *Synchronization:* Calls to this function do not introduce data
8264
  races  [[intro.multithread]] with calls to `operator()` or
8265
  `make_ready_at_thread_exit`.
8266
 
8267
  [*Note 1*: Such calls need not synchronize with each
8268
  other. — *end note*]
8269
 
8270
+ *Returns:* A `future` object that shares the same shared state as
8271
+ `*this`.
8272
+
8273
  *Throws:* A `future_error` object if an error occurs.
8274
 
8275
  *Error conditions:*
8276
 
8277
  - `future_already_retrieved` if `get_future` has already been called on
 
8331
  [*Note 2*: This constructs a new shared state for `*this`. The old
8332
  state is abandoned [[futures.state]]. — *end note*]
8333
 
8334
  *Throws:*
8335
 
8336
+ - `bad_alloc` if memory for the new shared state cannot be allocated.
8337
+ - Any exception thrown by the move constructor of the task stored in the
8338
  shared state.
8339
  - `future_error` with an error condition of `no_state` if `*this` has no
8340
  shared state.
8341
 
8342
  #### Globals <a id="futures.task.nonmembers">[[futures.task.nonmembers]]</a>
 
8348
 
8349
  *Effects:* As if by `x.swap(y)`.
8350
 
8351
  <!-- Link reference definitions -->
8352
  [alg.sorting]: algorithms.md#alg.sorting
8353
+ [allocator.requirements.general]: library.md#allocator.requirements.general
8354
+ [atomic.types.int.comp]: #atomic.types.int.comp
8355
+ [atomic.types.pointer.comp]: #atomic.types.pointer.comp
8356
+ [atomics]: #atomics
8357
+ [atomics.alias]: #atomics.alias
8358
+ [atomics.fences]: #atomics.fences
8359
+ [atomics.flag]: #atomics.flag
8360
+ [atomics.general]: #atomics.general
8361
+ [atomics.lockfree]: #atomics.lockfree
8362
+ [atomics.nonmembers]: #atomics.nonmembers
8363
+ [atomics.order]: #atomics.order
8364
+ [atomics.ref.float]: #atomics.ref.float
8365
+ [atomics.ref.generic]: #atomics.ref.generic
8366
+ [atomics.ref.generic.general]: #atomics.ref.generic.general
8367
+ [atomics.ref.int]: #atomics.ref.int
8368
+ [atomics.ref.memop]: #atomics.ref.memop
8369
+ [atomics.ref.ops]: #atomics.ref.ops
8370
+ [atomics.ref.pointer]: #atomics.ref.pointer
8371
+ [atomics.syn]: #atomics.syn
8372
+ [atomics.types.float]: #atomics.types.float
8373
+ [atomics.types.generic]: #atomics.types.generic
8374
+ [atomics.types.generic.general]: #atomics.types.generic.general
8375
+ [atomics.types.int]: #atomics.types.int
8376
+ [atomics.types.memop]: #atomics.types.memop
8377
+ [atomics.types.operations]: #atomics.types.operations
8378
+ [atomics.types.pointer]: #atomics.types.pointer
8379
+ [atomics.wait]: #atomics.wait
8380
  [barrier.syn]: #barrier.syn
8381
+ [basic.align]: basic.md#basic.align
8382
+ [basic.fundamental]: basic.md#basic.fundamental
8383
  [basic.life]: basic.md#basic.life
8384
  [basic.stc.thread]: basic.md#basic.stc.thread
8385
  [bitmask.types]: library.md#bitmask.types
8386
+ [cfenv]: numerics.md#cfenv
8387
  [class.prop]: class.md#class.prop
8388
+ [compliance]: library.md#compliance
8389
+ [concept.booleantestable]: concepts.md#concept.booleantestable
8390
  [condition.variable.syn]: #condition.variable.syn
8391
+ [conv.rval]: expr.md#conv.rval
8392
  [cpp17.defaultconstructible]: #cpp17.defaultconstructible
8393
  [cpp17.destructible]: #cpp17.destructible
8394
  [cpp17.moveassignable]: #cpp17.moveassignable
8395
  [cpp17.moveconstructible]: #cpp17.moveconstructible
8396
  [defns.block]: intro.md#defns.block
8397
  [except.terminate]: except.md#except.terminate
8398
+ [expr.pre]: expr.md#expr.pre
8399
+ [format.string.std]: utilities.md#format.string.std
8400
+ [func.invoke]: utilities.md#func.invoke
8401
  [func.require]: utilities.md#func.require
8402
+ [function.objects]: utilities.md#function.objects
8403
  [future.syn]: #future.syn
8404
  [futures]: #futures
8405
  [futures.async]: #futures.async
8406
  [futures.errors]: #futures.errors
8407
  [futures.future.error]: #futures.future.error
8408
  [futures.overview]: #futures.overview
8409
  [futures.promise]: #futures.promise
8410
  [futures.shared.future]: #futures.shared.future
8411
  [futures.state]: #futures.state
8412
  [futures.task]: #futures.task
8413
+ [futures.task.general]: #futures.task.general
8414
  [futures.task.members]: #futures.task.members
8415
  [futures.task.nonmembers]: #futures.task.nonmembers
8416
  [futures.unique.future]: #futures.unique.future
8417
  [intro.multithread]: basic.md#intro.multithread
8418
+ [intro.progress]: basic.md#intro.progress
8419
  [intro.races]: basic.md#intro.races
8420
  [latch.syn]: #latch.syn
8421
+ [limits.syn]: support.md#limits.syn
8422
  [mutex.syn]: #mutex.syn
8423
  [res.on.data.races]: library.md#res.on.data.races
8424
  [res.on.exception.handling]: library.md#res.on.exception.handling
8425
  [semaphore.syn]: #semaphore.syn
8426
  [shared.mutex.syn]: #shared.mutex.syn
8427
+ [stdatomic.h.syn]: #stdatomic.h.syn
8428
  [stopcallback]: #stopcallback
8429
  [stopcallback.cons]: #stopcallback.cons
8430
+ [stopcallback.general]: #stopcallback.general
8431
  [stopsource]: #stopsource
8432
  [stopsource.cons]: #stopsource.cons
8433
+ [stopsource.general]: #stopsource.general
8434
  [stopsource.mem]: #stopsource.mem
8435
  [stopsource.nonmembers]: #stopsource.nonmembers
8436
  [stoptoken]: #stoptoken
8437
  [stoptoken.cons]: #stoptoken.cons
8438
+ [stoptoken.general]: #stoptoken.general
8439
  [stoptoken.mem]: #stoptoken.mem
8440
  [stoptoken.nonmembers]: #stoptoken.nonmembers
8441
  [syserr]: diagnostics.md#syserr
8442
  [syserr.syserr]: diagnostics.md#syserr.syserr
8443
+ [term.padding.bits]: basic.md#term.padding.bits
8444
+ [term.unevaluated.operand]: expr.md#term.unevaluated.operand
8445
  [thread]: #thread
8446
  [thread.barrier]: #thread.barrier
8447
  [thread.barrier.class]: #thread.barrier.class
8448
+ [thread.barrier.general]: #thread.barrier.general
8449
  [thread.condition]: #thread.condition
8450
  [thread.condition.condvar]: #thread.condition.condvar
8451
  [thread.condition.condvarany]: #thread.condition.condvarany
8452
+ [thread.condition.condvarany.general]: #thread.condition.condvarany.general
8453
+ [thread.condition.general]: #thread.condition.general
8454
  [thread.condition.nonmember]: #thread.condition.nonmember
8455
  [thread.condvarany.intwait]: #thread.condvarany.intwait
8456
  [thread.condvarany.wait]: #thread.condvarany.wait
8457
  [thread.coord]: #thread.coord
8458
+ [thread.coord.general]: #thread.coord.general
8459
  [thread.general]: #thread.general
8460
  [thread.jthread.class]: #thread.jthread.class
8461
+ [thread.jthread.class.general]: #thread.jthread.class.general
8462
  [thread.jthread.cons]: #thread.jthread.cons
8463
  [thread.jthread.mem]: #thread.jthread.mem
8464
  [thread.jthread.special]: #thread.jthread.special
8465
  [thread.jthread.static]: #thread.jthread.static
8466
  [thread.jthread.stop]: #thread.jthread.stop
8467
  [thread.latch]: #thread.latch
8468
  [thread.latch.class]: #thread.latch.class
8469
+ [thread.latch.general]: #thread.latch.general
8470
  [thread.lock]: #thread.lock
8471
  [thread.lock.algorithm]: #thread.lock.algorithm
8472
+ [thread.lock.general]: #thread.lock.general
8473
  [thread.lock.guard]: #thread.lock.guard
8474
  [thread.lock.scoped]: #thread.lock.scoped
8475
  [thread.lock.shared]: #thread.lock.shared
8476
  [thread.lock.shared.cons]: #thread.lock.shared.cons
8477
+ [thread.lock.shared.general]: #thread.lock.shared.general
8478
  [thread.lock.shared.locking]: #thread.lock.shared.locking
8479
  [thread.lock.shared.mod]: #thread.lock.shared.mod
8480
  [thread.lock.shared.obs]: #thread.lock.shared.obs
8481
  [thread.lock.unique]: #thread.lock.unique
8482
  [thread.lock.unique.cons]: #thread.lock.unique.cons
8483
+ [thread.lock.unique.general]: #thread.lock.unique.general
8484
  [thread.lock.unique.locking]: #thread.lock.unique.locking
8485
  [thread.lock.unique.mod]: #thread.lock.unique.mod
8486
  [thread.lock.unique.obs]: #thread.lock.unique.obs
8487
  [thread.mutex]: #thread.mutex
8488
  [thread.mutex.class]: #thread.mutex.class
8489
+ [thread.mutex.general]: #thread.mutex.general
8490
  [thread.mutex.recursive]: #thread.mutex.recursive
8491
  [thread.mutex.requirements]: #thread.mutex.requirements
8492
  [thread.mutex.requirements.general]: #thread.mutex.requirements.general
8493
  [thread.mutex.requirements.mutex]: #thread.mutex.requirements.mutex
8494
+ [thread.mutex.requirements.mutex.general]: #thread.mutex.requirements.mutex.general
8495
  [thread.once]: #thread.once
8496
  [thread.once.callonce]: #thread.once.callonce
8497
  [thread.once.onceflag]: #thread.once.onceflag
8498
  [thread.req]: #thread.req
8499
  [thread.req.exception]: #thread.req.exception
8500
  [thread.req.lockable]: #thread.req.lockable
8501
  [thread.req.lockable.basic]: #thread.req.lockable.basic
8502
  [thread.req.lockable.general]: #thread.req.lockable.general
8503
  [thread.req.lockable.req]: #thread.req.lockable.req
8504
+ [thread.req.lockable.shared]: #thread.req.lockable.shared
8505
+ [thread.req.lockable.shared.timed]: #thread.req.lockable.shared.timed
8506
  [thread.req.lockable.timed]: #thread.req.lockable.timed
8507
  [thread.req.native]: #thread.req.native
8508
  [thread.req.paramname]: #thread.req.paramname
8509
  [thread.req.timing]: #thread.req.timing
8510
  [thread.sema]: #thread.sema
8511
  [thread.sema.cnt]: #thread.sema.cnt
8512
+ [thread.sema.general]: #thread.sema.general
8513
  [thread.sharedmutex.class]: #thread.sharedmutex.class
8514
  [thread.sharedmutex.requirements]: #thread.sharedmutex.requirements
8515
+ [thread.sharedmutex.requirements.general]: #thread.sharedmutex.requirements.general
8516
  [thread.sharedtimedmutex.class]: #thread.sharedtimedmutex.class
8517
  [thread.sharedtimedmutex.requirements]: #thread.sharedtimedmutex.requirements
8518
+ [thread.sharedtimedmutex.requirements.general]: #thread.sharedtimedmutex.requirements.general
8519
  [thread.stoptoken]: #thread.stoptoken
8520
  [thread.stoptoken.intro]: #thread.stoptoken.intro
8521
  [thread.stoptoken.syn]: #thread.stoptoken.syn
8522
  [thread.summary]: #thread.summary
8523
  [thread.syn]: #thread.syn
8524
  [thread.thread.algorithm]: #thread.thread.algorithm
8525
  [thread.thread.assign]: #thread.thread.assign
8526
  [thread.thread.class]: #thread.thread.class
8527
+ [thread.thread.class.general]: #thread.thread.class.general
8528
  [thread.thread.constr]: #thread.thread.constr
8529
  [thread.thread.destr]: #thread.thread.destr
8530
  [thread.thread.id]: #thread.thread.id
8531
  [thread.thread.member]: #thread.thread.member
8532
  [thread.thread.static]: #thread.thread.static
8533
  [thread.thread.this]: #thread.thread.this
8534
  [thread.threads]: #thread.threads
8535
+ [thread.threads.general]: #thread.threads.general
8536
  [thread.timedmutex.class]: #thread.timedmutex.class
8537
  [thread.timedmutex.recursive]: #thread.timedmutex.recursive
8538
  [thread.timedmutex.requirements]: #thread.timedmutex.requirements
8539
+ [thread.timedmutex.requirements.general]: #thread.timedmutex.requirements.general
8540
  [time]: time.md#time
8541
  [time.clock]: time.md#time.clock
8542
  [time.clock.req]: time.md#time.clock.req
8543
  [time.duration]: time.md#time.duration
8544
  [time.point]: time.md#time.point
8545
  [unord.hash]: utilities.md#unord.hash
8546
+ [util.sharedptr]: mem.md#util.sharedptr
8547
+ [util.smartptr.atomic]: #util.smartptr.atomic
8548
+ [util.smartptr.atomic.general]: #util.smartptr.atomic.general
8549
+ [util.smartptr.atomic.shared]: #util.smartptr.atomic.shared
8550
+ [util.smartptr.atomic.weak]: #util.smartptr.atomic.weak
8551
 
8552
+ [^1]: Implementations for which standard time units are meaningful will
8553
+ typically have a steady clock within their hardware implementation.
8554
+
8555
+ [^2]: That is, atomic operations on the same memory location via two
8556
+ different addresses will communicate atomically.