Clang Project

include/c++/7/bits/atomic_base.h
1// -*- C++ -*- header.
2
3// Copyright (C) 2008-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/atomic_base.h
26 *  This is an internal header file, included by other library headers.
27 *  Do not attempt to use it directly. @headername{atomic}
28 */
29
30#ifndef _GLIBCXX_ATOMIC_BASE_H
31#define _GLIBCXX_ATOMIC_BASE_H 1
32
33#pragma GCC system_header
34
35#include <bits/c++config.h>
36#include <stdint.h>
37#include <bits/atomic_lockfree_defines.h>
38
39#ifndef _GLIBCXX_ALWAYS_INLINE
40#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
41#endif
42
43namespace std _GLIBCXX_VISIBILITY(default)
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
46
47  /**
48   * @defgroup atomics Atomics
49   *
50   * Components for performing atomic operations.
51   * @{
52   */
53
54  /// Enumeration for memory_order
55  typedef enum memory_order
56    {
57      memory_order_relaxed,
58      memory_order_consume,
59      memory_order_acquire,
60      memory_order_release,
61      memory_order_acq_rel,
62      memory_order_seq_cst
63    } memory_order;
64
65  enum __memory_order_modifier
66    {
67      __memory_order_mask          = 0x0ffff,
68      __memory_order_modifier_mask = 0xffff0000,
69      __memory_order_hle_acquire   = 0x10000,
70      __memory_order_hle_release   = 0x20000
71    };
72
73  constexpr memory_order
74  operator|(memory_order __m__memory_order_modifier __mod)
75  {
76    return memory_order(__m | int(__mod));
77  }
78
79  constexpr memory_order
80  operator&(memory_order __m__memory_order_modifier __mod)
81  {
82    return memory_order(__m & int(__mod));
83  }
84
85  // Drop release ordering as per [atomics.types.operations.req]/21
86  constexpr memory_order
87  __cmpexch_failure_order2(memory_order __mnoexcept
88  {
89    return __m == memory_order_acq_rel ? memory_order_acquire
90      : __m == memory_order_release ? memory_order_relaxed : __m;
91  }
92
93  constexpr memory_order
94  __cmpexch_failure_order(memory_order __mnoexcept
95  {
96    return memory_order(__cmpexch_failure_order2(__m & __memory_order_mask)
97      | (__m & __memory_order_modifier_mask));
98  }
99
100  _GLIBCXX_ALWAYS_INLINE void
101  atomic_thread_fence(memory_order __mnoexcept
102  { __atomic_thread_fence(__m); }
103
104  _GLIBCXX_ALWAYS_INLINE void
105  atomic_signal_fence(memory_order __mnoexcept
106  { __atomic_signal_fence(__m); }
107
108  /// kill_dependency
109  template<typename _Tp>
110    inline _Tp
111    kill_dependency(_Tp __ynoexcept
112    {
113      _Tp __ret(__y);
114      return __ret;
115    }
116
117
118  // Base types for atomics.
119  template<typename _IntTp>
120    struct __atomic_base;
121
122
123#define ATOMIC_VAR_INIT(_VI) { _VI }
124
125  template<typename _Tp>
126    struct atomic;
127
128  template<typename _Tp>
129    struct atomic<_Tp*>;
130
131    /* The target's "set" value for test-and-set may not be exactly 1.  */
132#if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1
133    typedef bool __atomic_flag_data_type;
134#else
135    typedef unsigned char __atomic_flag_data_type;
136#endif
137
138  /**
139   *  @brief Base type for atomic_flag.
140   *
141   *  Base type is POD with data, allowing atomic_flag to derive from
142   *  it and meet the standard layout type requirement. In addition to
143   *  compatibility with a C interface, this allows different
144   *  implementations of atomic_flag to use the same atomic operation
145   *  functions, via a standard conversion to the __atomic_flag_base
146   *  argument.
147  */
148  _GLIBCXX_BEGIN_EXTERN_C
149
150  struct __atomic_flag_base
151  {
152    __atomic_flag_data_type _M_i;
153  };
154
155  _GLIBCXX_END_EXTERN_C
156
157#define ATOMIC_FLAG_INIT { 0 }
158
159  /// atomic_flag
160  struct atomic_flag : public __atomic_flag_base
161  {
162    atomic_flag() noexcept = default;
163    ~atomic_flag() noexcept = default;
164    atomic_flag(const atomic_flag&) = delete;
165    atomic_flagoperator=(const atomic_flag&) = delete;
166    atomic_flagoperator=(const atomic_flag&) volatile = delete;
167
168    // Conversion to ATOMIC_FLAG_INIT.
169    constexpr atomic_flag(bool __inoexcept
170      : __atomic_flag_base_S_init(__i) }
171    { }
172
173    _GLIBCXX_ALWAYS_INLINE bool
174    test_and_set(memory_order __m = memory_order_seq_cstnoexcept
175    {
176      return __atomic_test_and_set (&_M_i__m);
177    }
178
179    _GLIBCXX_ALWAYS_INLINE bool
180    test_and_set(memory_order __m = memory_order_seq_cstvolatile noexcept
181    {
182      return __atomic_test_and_set (&_M_i__m);
183    }
184
185    _GLIBCXX_ALWAYS_INLINE void
186    clear(memory_order __m = memory_order_seq_cstnoexcept
187    {
188      memory_order __b = __m & __memory_order_mask;
189      __glibcxx_assert(__b != memory_order_consume);
190      __glibcxx_assert(__b != memory_order_acquire);
191      __glibcxx_assert(__b != memory_order_acq_rel);
192
193      __atomic_clear (&_M_i__m);
194    }
195
196    _GLIBCXX_ALWAYS_INLINE void
197    clear(memory_order __m = memory_order_seq_cstvolatile noexcept
198    {
199      memory_order __b = __m & __memory_order_mask;
200      __glibcxx_assert(__b != memory_order_consume);
201      __glibcxx_assert(__b != memory_order_acquire);
202      __glibcxx_assert(__b != memory_order_acq_rel);
203
204      __atomic_clear (&_M_i__m);
205    }
206
207  private:
208    static constexpr __atomic_flag_data_type
209    _S_init(bool __i)
210    { return __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0; }
211  };
212
213
214  /// Base class for atomic integrals.
215  //
216  // For each of the integral types, define atomic_[integral type] struct
217  //
218  // atomic_bool     bool
219  // atomic_char     char
220  // atomic_schar    signed char
221  // atomic_uchar    unsigned char
222  // atomic_short    short
223  // atomic_ushort   unsigned short
224  // atomic_int      int
225  // atomic_uint     unsigned int
226  // atomic_long     long
227  // atomic_ulong    unsigned long
228  // atomic_llong    long long
229  // atomic_ullong   unsigned long long
230  // atomic_char16_t char16_t
231  // atomic_char32_t char32_t
232  // atomic_wchar_t  wchar_t
233  //
234  // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or
235  // 8 bytes, since that is what GCC built-in functions for atomic
236  // memory access expect.
237  template<typename _ITp>
238    struct __atomic_base
239    {
240    private:
241      typedef _ITp  __int_type;
242
243      static constexpr int _S_alignment =
244 sizeof(_ITp) > alignof(_ITp) ? sizeof(_ITp) : alignof(_ITp);
245
246      alignas(_S_alignment__int_type _M_i;
247
248    public:
249      __atomic_base() noexcept = default;
250      ~__atomic_base() noexcept = default;
251      __atomic_base(const __atomic_base&) = delete;
252      __atomic_base& operator=(const __atomic_base&) = delete;
253      __atomic_base& operator=(const __atomic_base&) volatile = delete;
254
255      // Requires __int_type convertible to _M_i.
256      constexpr __atomic_base(__int_type __inoexcept : _M_i (__i) { }
257
258      operator __int_type() const noexcept
259      { return load(); }
260
261      operator __int_type() const volatile noexcept
262      { return load(); }
263
264      __int_type
265      operator=(__int_type __inoexcept
266      {
267 store(__i);
268 return __i;
269      }
270
271      __int_type
272      operator=(__int_type __ivolatile noexcept
273      {
274 store(__i);
275 return __i;
276      }
277
278      __int_type
279      operator++(intnoexcept
280      { return fetch_add(1); }
281
282      __int_type
283      operator++(intvolatile noexcept
284      { return fetch_add(1); }
285
286      __int_type
287      operator--(intnoexcept
288      { return fetch_sub(1); }
289
290      __int_type
291      operator--(intvolatile noexcept
292      { return fetch_sub(1); }
293
294      __int_type
295      operator++() noexcept
296      { return __atomic_add_fetch(&_M_i1memory_order_seq_cst); }
297
298      __int_type
299      operator++() volatile noexcept
300      { return __atomic_add_fetch(&_M_i1memory_order_seq_cst); }
301
302      __int_type
303      operator--() noexcept
304      { return __atomic_sub_fetch(&_M_i1memory_order_seq_cst); }
305
306      __int_type
307      operator--() volatile noexcept
308      { return __atomic_sub_fetch(&_M_i1memory_order_seq_cst); }
309
310      __int_type
311      operator+=(__int_type __inoexcept
312      { return __atomic_add_fetch(&_M_i__imemory_order_seq_cst); }
313
314      __int_type
315      operator+=(__int_type __ivolatile noexcept
316      { return __atomic_add_fetch(&_M_i__imemory_order_seq_cst); }
317
318      __int_type
319      operator-=(__int_type __inoexcept
320      { return __atomic_sub_fetch(&_M_i__imemory_order_seq_cst); }
321
322      __int_type
323      operator-=(__int_type __ivolatile noexcept
324      { return __atomic_sub_fetch(&_M_i__imemory_order_seq_cst); }
325
326      __int_type
327      operator&=(__int_type __inoexcept
328      { return __atomic_and_fetch(&_M_i__imemory_order_seq_cst); }
329
330      __int_type
331      operator&=(__int_type __ivolatile noexcept
332      { return __atomic_and_fetch(&_M_i__imemory_order_seq_cst); }
333
334      __int_type
335      operator|=(__int_type __inoexcept
336      { return __atomic_or_fetch(&_M_i__imemory_order_seq_cst); }
337
338      __int_type
339      operator|=(__int_type __ivolatile noexcept
340      { return __atomic_or_fetch(&_M_i__imemory_order_seq_cst); }
341
342      __int_type
343      operator^=(__int_type __inoexcept
344      { return __atomic_xor_fetch(&_M_i__imemory_order_seq_cst); }
345
346      __int_type
347      operator^=(__int_type __ivolatile noexcept
348      { return __atomic_xor_fetch(&_M_i__imemory_order_seq_cst); }
349
350      bool
351      is_lock_free() const noexcept
352      {
353 // Use a fake, minimally aligned pointer.
354 return __atomic_is_lock_free(sizeof(_M_i),
355     reinterpret_cast<void *>(-__alignof(_M_i)));
356      }
357
358      bool
359      is_lock_free() const volatile noexcept
360      {
361 // Use a fake, minimally aligned pointer.
362 return __atomic_is_lock_free(sizeof(_M_i),
363     reinterpret_cast<void *>(-__alignof(_M_i)));
364      }
365
366      _GLIBCXX_ALWAYS_INLINE void
367      store(__int_type __imemory_order __m = memory_order_seq_cstnoexcept
368      {
369 memory_order __b = __m & __memory_order_mask;
370 __glibcxx_assert(__b != memory_order_acquire);
371 __glibcxx_assert(__b != memory_order_acq_rel);
372 __glibcxx_assert(__b != memory_order_consume);
373
374 __atomic_store_n(&_M_i__i__m);
375      }
376
377      _GLIBCXX_ALWAYS_INLINE void
378      store(__int_type __i,
379     memory_order __m = memory_order_seq_cstvolatile noexcept
380      {
381 memory_order __b = __m & __memory_order_mask;
382 __glibcxx_assert(__b != memory_order_acquire);
383 __glibcxx_assert(__b != memory_order_acq_rel);
384 __glibcxx_assert(__b != memory_order_consume);
385
386 __atomic_store_n(&_M_i__i__m);
387      }
388
389      _GLIBCXX_ALWAYS_INLINE __int_type
390      load(memory_order __m = memory_order_seq_cstconst noexcept
391      {
392 memory_order __b = __m & __memory_order_mask;
393 __glibcxx_assert(__b != memory_order_release);
394 __glibcxx_assert(__b != memory_order_acq_rel);
395
396 return __atomic_load_n(&_M_i__m);
397      }
398
399      _GLIBCXX_ALWAYS_INLINE __int_type
400      load(memory_order __m = memory_order_seq_cstconst volatile noexcept
401      {
402 memory_order __b = __m & __memory_order_mask;
403 __glibcxx_assert(__b != memory_order_release);
404 __glibcxx_assert(__b != memory_order_acq_rel);
405
406 return __atomic_load_n(&_M_i__m);
407      }
408
409      _GLIBCXX_ALWAYS_INLINE __int_type
410      exchange(__int_type __i,
411        memory_order __m = memory_order_seq_cstnoexcept
412      {
413 return __atomic_exchange_n(&_M_i__i__m);
414      }
415
416
417      _GLIBCXX_ALWAYS_INLINE __int_type
418      exchange(__int_type __i,
419        memory_order __m = memory_order_seq_cstvolatile noexcept
420      {
421 return __atomic_exchange_n(&_M_i__i__m);
422      }
423
424      _GLIBCXX_ALWAYS_INLINE bool
425      compare_exchange_weak(__int_type__i1__int_type __i2,
426     memory_order __m1memory_order __m2noexcept
427      {
428 memory_order __b2 = __m2 & __memory_order_mask;
429 memory_order __b1 = __m1 & __memory_order_mask;
430 __glibcxx_assert(__b2 != memory_order_release);
431 __glibcxx_assert(__b2 != memory_order_acq_rel);
432 __glibcxx_assert(__b2 <= __b1);
433
434 return __atomic_compare_exchange_n(&_M_i, &__i1__i21__m1__m2);
435      }
436
437      _GLIBCXX_ALWAYS_INLINE bool
438      compare_exchange_weak(__int_type__i1__int_type __i2,
439     memory_order __m1,
440     memory_order __m2volatile noexcept
441      {
442 memory_order __b2 = __m2 & __memory_order_mask;
443 memory_order __b1 = __m1 & __memory_order_mask;
444 __glibcxx_assert(__b2 != memory_order_release);
445 __glibcxx_assert(__b2 != memory_order_acq_rel);
446 __glibcxx_assert(__b2 <= __b1);
447
448 return __atomic_compare_exchange_n(&_M_i, &__i1__i21__m1__m2);
449      }
450
451      _GLIBCXX_ALWAYS_INLINE bool
452      compare_exchange_weak(__int_type__i1__int_type __i2,
453     memory_order __m = memory_order_seq_cstnoexcept
454      {
455 return compare_exchange_weak(__i1__i2__m,
456      __cmpexch_failure_order(__m));
457      }
458
459      _GLIBCXX_ALWAYS_INLINE bool
460      compare_exchange_weak(__int_type__i1__int_type __i2,
461    memory_order __m = memory_order_seq_cstvolatile noexcept
462      {
463 return compare_exchange_weak(__i1__i2__m,
464      __cmpexch_failure_order(__m));
465      }
466
467      _GLIBCXX_ALWAYS_INLINE bool
468      compare_exchange_strong(__int_type__i1__int_type __i2,
469       memory_order __m1memory_order __m2noexcept
470      {
471 memory_order __b2 = __m2 & __memory_order_mask;
472 memory_order __b1 = __m1 & __memory_order_mask;
473 __glibcxx_assert(__b2 != memory_order_release);
474 __glibcxx_assert(__b2 != memory_order_acq_rel);
475 __glibcxx_assert(__b2 <= __b1);
476
477 return __atomic_compare_exchange_n(&_M_i, &__i1__i20__m1__m2);
478      }
479
480      _GLIBCXX_ALWAYS_INLINE bool
481      compare_exchange_strong(__int_type__i1__int_type __i2,
482       memory_order __m1,
483       memory_order __m2volatile noexcept
484      {
485 memory_order __b2 = __m2 & __memory_order_mask;
486 memory_order __b1 = __m1 & __memory_order_mask;
487
488 __glibcxx_assert(__b2 != memory_order_release);
489 __glibcxx_assert(__b2 != memory_order_acq_rel);
490 __glibcxx_assert(__b2 <= __b1);
491
492 return __atomic_compare_exchange_n(&_M_i, &__i1__i20__m1__m2);
493      }
494
495      _GLIBCXX_ALWAYS_INLINE bool
496      compare_exchange_strong(__int_type__i1__int_type __i2,
497       memory_order __m = memory_order_seq_cstnoexcept
498      {
499 return compare_exchange_strong(__i1__i2__m,
500        __cmpexch_failure_order(__m));
501      }
502
503      _GLIBCXX_ALWAYS_INLINE bool
504      compare_exchange_strong(__int_type__i1__int_type __i2,
505  memory_order __m = memory_order_seq_cstvolatile noexcept
506      {
507 return compare_exchange_strong(__i1__i2__m,
508        __cmpexch_failure_order(__m));
509      }
510
511      _GLIBCXX_ALWAYS_INLINE __int_type
512      fetch_add(__int_type __i,
513 memory_order __m = memory_order_seq_cstnoexcept
514      { return __atomic_fetch_add(&_M_i__i__m); }
515
516      _GLIBCXX_ALWAYS_INLINE __int_type
517      fetch_add(__int_type __i,
518 memory_order __m = memory_order_seq_cstvolatile noexcept
519      { return __atomic_fetch_add(&_M_i__i__m); }
520
521      _GLIBCXX_ALWAYS_INLINE __int_type
522      fetch_sub(__int_type __i,
523 memory_order __m = memory_order_seq_cstnoexcept
524      { return __atomic_fetch_sub(&_M_i__i__m); }
525
526      _GLIBCXX_ALWAYS_INLINE __int_type
527      fetch_sub(__int_type __i,
528 memory_order __m = memory_order_seq_cstvolatile noexcept
529      { return __atomic_fetch_sub(&_M_i__i__m); }
530
531      _GLIBCXX_ALWAYS_INLINE __int_type
532      fetch_and(__int_type __i,
533 memory_order __m = memory_order_seq_cstnoexcept
534      { return __atomic_fetch_and(&_M_i__i__m); }
535
536      _GLIBCXX_ALWAYS_INLINE __int_type
537      fetch_and(__int_type __i,
538 memory_order __m = memory_order_seq_cstvolatile noexcept
539      { return __atomic_fetch_and(&_M_i__i__m); }
540
541      _GLIBCXX_ALWAYS_INLINE __int_type
542      fetch_or(__int_type __i,
543        memory_order __m = memory_order_seq_cstnoexcept
544      { return __atomic_fetch_or(&_M_i__i__m); }
545
546      _GLIBCXX_ALWAYS_INLINE __int_type
547      fetch_or(__int_type __i,
548        memory_order __m = memory_order_seq_cstvolatile noexcept
549      { return __atomic_fetch_or(&_M_i__i__m); }
550
551      _GLIBCXX_ALWAYS_INLINE __int_type
552      fetch_xor(__int_type __i,
553 memory_order __m = memory_order_seq_cstnoexcept
554      { return __atomic_fetch_xor(&_M_i__i__m); }
555
556      _GLIBCXX_ALWAYS_INLINE __int_type
557      fetch_xor(__int_type __i,
558 memory_order __m = memory_order_seq_cstvolatile noexcept
559      { return __atomic_fetch_xor(&_M_i__i__m); }
560    };
561
562
563  /// Partial specialization for pointer types.
564  template<typename _PTp>
565    struct __atomic_base<_PTp*>
566    {
567    private:
568      typedef _PTp*  __pointer_type;
569
570      __pointer_type  _M_p;
571
572      // Factored out to facilitate explicit specialization.
573      constexpr ptrdiff_t
574      _M_type_size(ptrdiff_t __dconst { return __d * sizeof(_PTp); }
575
576      constexpr ptrdiff_t
577      _M_type_size(ptrdiff_t __dconst volatile { return __d * sizeof(_PTp); }
578
579    public:
580      __atomic_base() noexcept = default;
581      ~__atomic_base() noexcept = default;
582      __atomic_base(const __atomic_base&) = delete;
583      __atomic_base& operator=(const __atomic_base&) = delete;
584      __atomic_base& operator=(const __atomic_base&) volatile = delete;
585
586      // Requires __pointer_type convertible to _M_p.
587      constexpr __atomic_base(__pointer_type __pnoexcept : _M_p (__p) { }
588
589      operator __pointer_type() const noexcept
590      { return load(); }
591
592      operator __pointer_type() const volatile noexcept
593      { return load(); }
594
595      __pointer_type
596      operator=(__pointer_type __pnoexcept
597      {
598 store(__p);
599 return __p;
600      }
601
602      __pointer_type
603      operator=(__pointer_type __pvolatile noexcept
604      {
605 store(__p);
606 return __p;
607      }
608
609      __pointer_type
610      operator++(intnoexcept
611      { return fetch_add(1); }
612
613      __pointer_type
614      operator++(intvolatile noexcept
615      { return fetch_add(1); }
616
617      __pointer_type
618      operator--(intnoexcept
619      { return fetch_sub(1); }
620
621      __pointer_type
622      operator--(intvolatile noexcept
623      { return fetch_sub(1); }
624
625      __pointer_type
626      operator++() noexcept
627      { return __atomic_add_fetch(&_M_p, _M_type_size(1),
628   memory_order_seq_cst); }
629
630      __pointer_type
631      operator++() volatile noexcept
632      { return __atomic_add_fetch(&_M_p, _M_type_size(1),
633   memory_order_seq_cst); }
634
635      __pointer_type
636      operator--() noexcept
637      { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
638   memory_order_seq_cst); }
639
640      __pointer_type
641      operator--() volatile noexcept
642      { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
643   memory_order_seq_cst); }
644
645      __pointer_type
646      operator+=(ptrdiff_t __dnoexcept
647      { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
648   memory_order_seq_cst); }
649
650      __pointer_type
651      operator+=(ptrdiff_t __dvolatile noexcept
652      { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
653   memory_order_seq_cst); }
654
655      __pointer_type
656      operator-=(ptrdiff_t __dnoexcept
657      { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
658   memory_order_seq_cst); }
659
660      __pointer_type
661      operator-=(ptrdiff_t __dvolatile noexcept
662      { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
663   memory_order_seq_cst); }
664
665      bool
666      is_lock_free() const noexcept
667      {
668 // Produce a fake, minimally aligned pointer.
669 return __atomic_is_lock_free(sizeof(_M_p),
670     reinterpret_cast<void *>(-__alignof(_M_p)));
671      }
672
673      bool
674      is_lock_free() const volatile noexcept
675      {
676 // Produce a fake, minimally aligned pointer.
677 return __atomic_is_lock_free(sizeof(_M_p),
678     reinterpret_cast<void *>(-__alignof(_M_p)));
679      }
680
681      _GLIBCXX_ALWAYS_INLINE void
682      store(__pointer_type __p,
683     memory_order __m = memory_order_seq_cstnoexcept
684      {
685        memory_order __b = __m & __memory_order_mask;
686
687 __glibcxx_assert(__b != memory_order_acquire);
688 __glibcxx_assert(__b != memory_order_acq_rel);
689 __glibcxx_assert(__b != memory_order_consume);
690
691 __atomic_store_n(&_M_p__p__m);
692      }
693
694      _GLIBCXX_ALWAYS_INLINE void
695      store(__pointer_type __p,
696     memory_order __m = memory_order_seq_cstvolatile noexcept
697      {
698 memory_order __b = __m & __memory_order_mask;
699 __glibcxx_assert(__b != memory_order_acquire);
700 __glibcxx_assert(__b != memory_order_acq_rel);
701 __glibcxx_assert(__b != memory_order_consume);
702
703 __atomic_store_n(&_M_p__p__m);
704      }
705
706      _GLIBCXX_ALWAYS_INLINE __pointer_type
707      load(memory_order __m = memory_order_seq_cstconst noexcept
708      {
709 memory_order __b = __m & __memory_order_mask;
710 __glibcxx_assert(__b != memory_order_release);
711 __glibcxx_assert(__b != memory_order_acq_rel);
712
713 return __atomic_load_n(&_M_p__m);
714      }
715
716      _GLIBCXX_ALWAYS_INLINE __pointer_type
717      load(memory_order __m = memory_order_seq_cstconst volatile noexcept
718      {
719 memory_order __b = __m & __memory_order_mask;
720 __glibcxx_assert(__b != memory_order_release);
721 __glibcxx_assert(__b != memory_order_acq_rel);
722
723 return __atomic_load_n(&_M_p__m);
724      }
725
726      _GLIBCXX_ALWAYS_INLINE __pointer_type
727      exchange(__pointer_type __p,
728        memory_order __m = memory_order_seq_cstnoexcept
729      {
730 return __atomic_exchange_n(&_M_p__p__m);
731      }
732
733
734      _GLIBCXX_ALWAYS_INLINE __pointer_type
735      exchange(__pointer_type __p,
736        memory_order __m = memory_order_seq_cstvolatile noexcept
737      {
738 return __atomic_exchange_n(&_M_p__p__m);
739      }
740
741      _GLIBCXX_ALWAYS_INLINE bool
742      compare_exchange_strong(__pointer_type__p1__pointer_type __p2,
743       memory_order __m1,
744       memory_order __m2noexcept
745      {
746 memory_order __b2 = __m2 & __memory_order_mask;
747 memory_order __b1 = __m1 & __memory_order_mask;
748 __glibcxx_assert(__b2 != memory_order_release);
749 __glibcxx_assert(__b2 != memory_order_acq_rel);
750 __glibcxx_assert(__b2 <= __b1);
751
752 return __atomic_compare_exchange_n(&_M_p, &__p1__p20__m1__m2);
753      }
754
755      _GLIBCXX_ALWAYS_INLINE bool
756      compare_exchange_strong(__pointer_type__p1__pointer_type __p2,
757       memory_order __m1,
758       memory_order __m2volatile noexcept
759      {
760 memory_order __b2 = __m2 & __memory_order_mask;
761 memory_order __b1 = __m1 & __memory_order_mask;
762
763 __glibcxx_assert(__b2 != memory_order_release);
764 __glibcxx_assert(__b2 != memory_order_acq_rel);
765 __glibcxx_assert(__b2 <= __b1);
766
767 return __atomic_compare_exchange_n(&_M_p, &__p1__p20__m1__m2);
768      }
769
770      _GLIBCXX_ALWAYS_INLINE __pointer_type
771      fetch_add(ptrdiff_t __d,
772 memory_order __m = memory_order_seq_cstnoexcept
773      { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
774
775      _GLIBCXX_ALWAYS_INLINE __pointer_type
776      fetch_add(ptrdiff_t __d,
777 memory_order __m = memory_order_seq_cstvolatile noexcept
778      { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
779
780      _GLIBCXX_ALWAYS_INLINE __pointer_type
781      fetch_sub(ptrdiff_t __d,
782 memory_order __m = memory_order_seq_cstnoexcept
783      { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
784
785      _GLIBCXX_ALWAYS_INLINE __pointer_type
786      fetch_sub(ptrdiff_t __d,
787 memory_order __m = memory_order_seq_cstvolatile noexcept
788      { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
789    };
790
791  // @} group atomics
792
793_GLIBCXX_END_NAMESPACE_VERSION
794// namespace std
795
796#endif
797
std::__atomic_flag_base::_M_i
std::atomic_flag::test_and_set
std::atomic_flag::test_and_set
std::atomic_flag::clear
std::atomic_flag::clear
std::atomic_flag::_S_init
std::__atomic_base::_S_alignment
std::__atomic_base::_M_i
std::__atomic_base::is_lock_free
std::__atomic_base::is_lock_free
std::__atomic_base::store
std::__atomic_base::store
std::__atomic_base::load
std::__atomic_base::load
std::__atomic_base::exchange
std::__atomic_base::exchange
std::__atomic_base::compare_exchange_weak
std::__atomic_base::compare_exchange_weak
std::__atomic_base::compare_exchange_weak
std::__atomic_base::compare_exchange_weak
std::__atomic_base::compare_exchange_strong
std::__atomic_base::compare_exchange_strong
std::__atomic_base::compare_exchange_strong
std::__atomic_base::compare_exchange_strong
std::__atomic_base::fetch_add
std::__atomic_base::fetch_add
std::__atomic_base::fetch_sub
std::__atomic_base::fetch_sub
std::__atomic_base::fetch_and
std::__atomic_base::fetch_and
std::__atomic_base::fetch_or
std::__atomic_base::fetch_or
std::__atomic_base::fetch_xor
std::__atomic_base::fetch_xor
std::__atomic_base::_M_p
std::__atomic_base::_M_type_size
std::__atomic_base::_M_type_size
std::__atomic_base::is_lock_free
std::__atomic_base::is_lock_free
std::__atomic_base::store
std::__atomic_base::store
std::__atomic_base::load
std::__atomic_base::load
std::__atomic_base::exchange
std::__atomic_base::exchange
std::__atomic_base::compare_exchange_strong
std::__atomic_base::compare_exchange_strong
std::__atomic_base::fetch_add
std::__atomic_base::fetch_add
std::__atomic_base::fetch_sub
std::__atomic_base::fetch_sub