OSDN Git Service

2010-01-29 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / atomic
1 // -*- C++ -*- header.
2
3 // Copyright (C) 2008, 2009
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 // <http://www.gnu.org/licenses/>.
25
26 /** @file atomic
27  *  This is a Standard C++ Library header.
28  */
29
30 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
31 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
32
33 #ifndef _GLIBCXX_ATOMIC
34 #define _GLIBCXX_ATOMIC 1
35
36 #pragma GCC system_header
37
38 #ifndef __GXX_EXPERIMENTAL_CXX0X__
39 # include <c++0x_warning.h>
40 #endif
41
42 #include <bits/atomic_base.h>
43 #include <cstddef>
44
45 _GLIBCXX_BEGIN_NAMESPACE(std)
46
47   /**
48    * @addtogroup atomics
49    * @{
50    */
51
52   /// kill_dependency
53   template<typename _Tp>
54     inline _Tp
55     kill_dependency(_Tp __y)
56     {
57       _Tp ret(__y);
58       return ret;
59     }
60
61   inline memory_order
62   __calculate_memory_order(memory_order __m)
63   {
64     const bool __cond1 = __m == memory_order_release;
65     const bool __cond2 = __m == memory_order_acq_rel;
66     memory_order __mo1(__cond1 ? memory_order_relaxed : __m);
67     memory_order __mo2(__cond2 ? memory_order_acquire : __mo1);
68     return __mo2;
69   }
70
71   //
72   // Three nested namespaces for atomic implementation details.
73   //
74   // The nested namespace inlined into std:: is determined by the value
75   // of the _GLIBCXX_ATOMIC_PROPERTY macro and the resulting
76   // ATOMIC_*_LOCK_FREE macros. See file atomic_base.h.
77   //
78   // 0 == __atomic0 == Never lock-free
79   // 1 == __atomic1 == Best available, sometimes lock-free
80   // 2 == __atomic2 == Always lock-free
81 #include <bits/atomic_0.h>
82 #include <bits/atomic_2.h>
83
84   /// atomic
85   /// 29.4.3, Generic atomic type, primary class template.
86   template<typename _Tp>
87     struct atomic
88     {
89     private:
90       _Tp _M_i;
91
92     public:
93       atomic() = default;
94       ~atomic() = default;
95       atomic(const atomic&) = delete;
96       atomic& operator=(const atomic&) volatile = delete;
97
98       atomic(_Tp __i) : _M_i(__i) { }
99
100       operator _Tp() const;
101
102       _Tp
103       operator=(_Tp __i) { store(__i); return __i; }
104
105       bool
106       is_lock_free() const volatile;
107
108       void
109       store(_Tp, memory_order = memory_order_seq_cst) volatile;
110
111       _Tp
112       load(memory_order = memory_order_seq_cst) const volatile;
113
114       _Tp
115       exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile;
116
117       bool
118       compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile;
119
120       bool
121       compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile;
122
123       bool
124       compare_exchange_weak(_Tp&, _Tp,
125                             memory_order = memory_order_seq_cst) volatile;
126
127       bool
128       compare_exchange_strong(_Tp&, _Tp,
129                               memory_order = memory_order_seq_cst) volatile;
130     };
131
132
133   /// Partial specialization for pointer types.
134   template<typename _Tp>
135     struct atomic<_Tp*> : atomic_address
136     {
137       atomic() = default;
138       ~atomic() = default;
139       atomic(const atomic&) = delete;
140       atomic& operator=(const atomic&) volatile = delete;
141
142       atomic(_Tp* __v) : atomic_address(__v) { }
143
144       void
145       store(_Tp*, memory_order = memory_order_seq_cst);
146
147       _Tp*
148       load(memory_order = memory_order_seq_cst) const;
149
150       _Tp*
151       exchange(_Tp*, memory_order = memory_order_seq_cst);
152
153       bool
154       compare_exchange_weak(_Tp*&, _Tp*, memory_order, memory_order);
155
156       bool
157       compare_exchange_strong(_Tp*&, _Tp*, memory_order, memory_order);
158
159       bool
160       compare_exchange_weak(_Tp*&, _Tp*, memory_order = memory_order_seq_cst);
161
162       bool
163       compare_exchange_strong(_Tp*&, _Tp*, memory_order = memory_order_seq_cst);
164
165       _Tp*
166       fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst);
167
168       _Tp*
169       fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst);
170
171       operator _Tp*() const
172       { return load(); }
173
174       _Tp*
175       operator=(_Tp* __v)
176       {
177         store(__v);
178         return __v;
179       }
180
181       _Tp*
182       operator++(int) { return fetch_add(1); }
183
184       _Tp*
185       operator--(int) { return fetch_sub(1); }
186
187       _Tp*
188       operator++() { return fetch_add(1) + 1; }
189
190       _Tp*
191       operator--() { return fetch_sub(1) - 1; }
192
193       _Tp*
194       operator+=(ptrdiff_t __d)
195       { return fetch_add(__d) + __d; }
196
197       _Tp*
198       operator-=(ptrdiff_t __d)
199       { return fetch_sub(__d) - __d; }
200     };
201
202
203   /// Explicit specialization for void*
204   template<>
205     struct atomic<void*> : public atomic_address
206     {
207       typedef void*                     __integral_type;
208       typedef atomic_address            __base_type;
209
210       atomic() = default;
211       ~atomic() = default;
212       atomic(const atomic&) = delete;
213       atomic& operator=(const atomic&) volatile = delete;
214
215       atomic(__integral_type __i) : __base_type(__i) { }
216
217       using __base_type::operator __integral_type;
218       using __base_type::operator=;
219     };
220
221   /// Explicit specialization for bool.
222   template<>
223     struct atomic<bool> : public atomic_bool
224     {
225       typedef bool                      __integral_type;
226       typedef atomic_bool               __base_type;
227
228       atomic() = default;
229       ~atomic() = default;
230       atomic(const atomic&) = delete;
231       atomic& operator=(const atomic&) volatile = delete;
232
233       atomic(__integral_type __i) : __base_type(__i) { }
234
235       using __base_type::operator __integral_type;
236       using __base_type::operator=;
237     };
238
239   /// Explicit specialization for char.
240   template<>
241     struct atomic<char> : public atomic_char
242     {
243       typedef char                      __integral_type;
244       typedef atomic_char               __base_type;
245
246       atomic() = default;
247       ~atomic() = default;
248       atomic(const atomic&) = delete;
249       atomic& operator=(const atomic&) volatile = delete;
250
251       atomic(__integral_type __i) : __base_type(__i) { }
252
253       using __base_type::operator __integral_type;
254       using __base_type::operator=;
255     };
256
257   /// Explicit specialization for signed char.
258   template<>
259     struct atomic<signed char> : public atomic_schar
260     {
261       typedef signed char               __integral_type;
262       typedef atomic_schar              __base_type;
263
264       atomic() = default;
265       ~atomic() = default;
266       atomic(const atomic&) = delete;
267       atomic& operator=(const atomic&) volatile = delete;
268
269       atomic(__integral_type __i) : __base_type(__i) { }
270
271       using __base_type::operator __integral_type;
272       using __base_type::operator=;
273     };
274
275   /// Explicit specialization for unsigned char.
276   template<>
277     struct atomic<unsigned char> : public atomic_uchar
278     {
279       typedef unsigned char             __integral_type;
280       typedef atomic_uchar              __base_type;
281
282       atomic() = default;
283       ~atomic() = default;
284       atomic(const atomic&) = delete;
285       atomic& operator=(const atomic&) volatile = delete;
286
287       atomic(__integral_type __i) : __base_type(__i) { }
288
289       using __base_type::operator __integral_type;
290       using __base_type::operator=;
291     };
292
293   /// Explicit specialization for short.
294   template<>
295     struct atomic<short> : public atomic_short
296     {
297       typedef short                     __integral_type;
298       typedef atomic_short              __base_type;
299
300       atomic() = default;
301       ~atomic() = default;
302       atomic(const atomic&) = delete;
303       atomic& operator=(const atomic&) volatile = delete;
304
305       atomic(__integral_type __i) : __base_type(__i) { }
306
307       using __base_type::operator __integral_type;
308       using __base_type::operator=;
309     };
310
311   /// Explicit specialization for unsigned short.
312   template<>
313     struct atomic<unsigned short> : public atomic_ushort
314     {
315       typedef unsigned short            __integral_type;
316       typedef atomic_ushort             __base_type;
317
318       atomic() = default;
319       ~atomic() = default;
320       atomic(const atomic&) = delete;
321       atomic& operator=(const atomic&) volatile = delete;
322
323       atomic(__integral_type __i) : __base_type(__i) { }
324
325       using __base_type::operator __integral_type;
326       using __base_type::operator=;
327     };
328
329   /// Explicit specialization for int.
330   template<>
331     struct atomic<int> : atomic_int
332     {
333       typedef int                       __integral_type;
334       typedef atomic_int                __base_type;
335
336       atomic() = default;
337       ~atomic() = default;
338       atomic(const atomic&) = delete;
339       atomic& operator=(const atomic&) volatile = delete;
340
341       atomic(__integral_type __i) : __base_type(__i) { }
342
343       using __base_type::operator __integral_type;
344       using __base_type::operator=;
345     };
346
347   /// Explicit specialization for unsigned int.
348   template<>
349     struct atomic<unsigned int> : public atomic_uint
350     {
351       typedef unsigned int              __integral_type;
352       typedef atomic_uint               __base_type;
353
354       atomic() = default;
355       ~atomic() = default;
356       atomic(const atomic&) = delete;
357       atomic& operator=(const atomic&) volatile = delete;
358
359       atomic(__integral_type __i) : __base_type(__i) { }
360
361       using __base_type::operator __integral_type;
362       using __base_type::operator=;
363     };
364
365   /// Explicit specialization for long.
366   template<>
367     struct atomic<long> : public atomic_long
368     {
369       typedef long                      __integral_type;
370       typedef atomic_long               __base_type;
371
372       atomic() = default;
373       ~atomic() = default;
374       atomic(const atomic&) = delete;
375       atomic& operator=(const atomic&) volatile = delete;
376
377       atomic(__integral_type __i) : __base_type(__i) { }
378
379       using __base_type::operator __integral_type;
380       using __base_type::operator=;
381     };
382
383   /// Explicit specialization for unsigned long.
384   template<>
385     struct atomic<unsigned long> : public atomic_ulong
386     {
387       typedef unsigned long             __integral_type;
388       typedef atomic_ulong              __base_type;
389
390       atomic() = default;
391       ~atomic() = default;
392       atomic(const atomic&) = delete;
393       atomic& operator=(const atomic&) volatile = delete;
394
395       atomic(__integral_type __i) : __base_type(__i) { }
396
397       using __base_type::operator __integral_type;
398       using __base_type::operator=;
399     };
400
401   /// Explicit specialization for long long.
402   template<>
403     struct atomic<long long> : public atomic_llong
404     {
405       typedef long long                 __integral_type;
406       typedef atomic_llong              __base_type;
407
408       atomic() = default;
409       ~atomic() = default;
410       atomic(const atomic&) = delete;
411       atomic& operator=(const atomic&) volatile = delete;
412
413       atomic(__integral_type __i) : __base_type(__i) { }
414
415       using __base_type::operator __integral_type;
416       using __base_type::operator=;
417     };
418
419   /// Explicit specialization for unsigned long long.
420   template<>
421     struct atomic<unsigned long long> : public atomic_ullong
422     {
423       typedef unsigned long long        __integral_type;
424       typedef atomic_ullong             __base_type;
425
426       atomic() = default;
427       ~atomic() = default;
428       atomic(const atomic&) = delete;
429       atomic& operator=(const atomic&) volatile = delete;
430
431       atomic(__integral_type __i) : __base_type(__i) { }
432
433       using __base_type::operator __integral_type;
434       using __base_type::operator=;
435     };
436
437   /// Explicit specialization for wchar_t.
438   template<>
439     struct atomic<wchar_t> : public atomic_wchar_t
440     {
441       typedef wchar_t                   __integral_type;
442       typedef atomic_wchar_t            __base_type;
443
444       atomic() = default;
445       ~atomic() = default;
446       atomic(const atomic&) = delete;
447       atomic& operator=(const atomic&) volatile = delete;
448
449       atomic(__integral_type __i) : __base_type(__i) { }
450
451       using __base_type::operator __integral_type;
452       using __base_type::operator=;
453     };
454
455   /// Explicit specialization for char16_t.
456   template<>
457     struct atomic<char16_t> : public atomic_char16_t
458     {
459       typedef char16_t                  __integral_type;
460       typedef atomic_char16_t           __base_type;
461
462       atomic() = default;
463       ~atomic() = default;
464       atomic(const atomic&) = delete;
465       atomic& operator=(const atomic&) volatile = delete;
466
467       atomic(__integral_type __i) : __base_type(__i) { }
468
469       using __base_type::operator __integral_type;
470       using __base_type::operator=;
471     };
472
473   /// Explicit specialization for char32_t.
474   template<>
475     struct atomic<char32_t> : public atomic_char32_t
476     {
477       typedef char32_t                  __integral_type;
478       typedef atomic_char32_t           __base_type;
479
480       atomic() = default;
481       ~atomic() = default;
482       atomic(const atomic&) = delete;
483       atomic& operator=(const atomic&) volatile = delete;
484
485       atomic(__integral_type __i) : __base_type(__i) { }
486
487       using __base_type::operator __integral_type;
488       using __base_type::operator=;
489     };
490
491
492   template<typename _Tp>
493     _Tp*
494     atomic<_Tp*>::load(memory_order __m) const
495     { return static_cast<_Tp*>(atomic_address::load(__m)); }
496
497   template<typename _Tp>
498     _Tp*
499     atomic<_Tp*>::exchange(_Tp* __v, memory_order __m)
500     { return static_cast<_Tp*>(atomic_address::exchange(__v, __m)); }
501
502   template<typename _Tp>
503     bool
504     atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v, memory_order __m1,
505                                         memory_order __m2)
506     {
507       void** __vr = reinterpret_cast<void**>(&__r);
508       void* __vv = static_cast<void*>(__v);
509       return atomic_address::compare_exchange_weak(*__vr, __vv, __m1, __m2);
510     }
511
512   template<typename _Tp>
513     bool
514     atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
515                                           memory_order __m1,
516                                           memory_order __m2)
517     {
518       void** __vr = reinterpret_cast<void**>(&__r);
519       void* __vv = static_cast<void*>(__v);
520       return atomic_address::compare_exchange_strong(*__vr, __vv, __m1, __m2);
521     }
522
523   template<typename _Tp>
524     bool
525     atomic<_Tp*>::compare_exchange_weak(_Tp*& __r, _Tp* __v,
526                                         memory_order __m)
527     {
528       return compare_exchange_weak(__r, __v, __m,
529                                    __calculate_memory_order(__m));
530     }
531
532   template<typename _Tp>
533     bool
534     atomic<_Tp*>::compare_exchange_strong(_Tp*& __r, _Tp* __v,
535                                         memory_order __m)
536     {
537       return compare_exchange_strong(__r, __v, __m,
538                                      __calculate_memory_order(__m));
539     }
540
541   template<typename _Tp>
542     _Tp*
543     atomic<_Tp*>::fetch_add(ptrdiff_t __d, memory_order __m)
544     {
545       void* __p = atomic_fetch_add_explicit(this, sizeof(_Tp) * __d, __m);
546       return static_cast<_Tp*>(__p);
547     }
548
549   template<typename _Tp>
550     _Tp*
551     atomic<_Tp*>::fetch_sub(ptrdiff_t __d, memory_order __m)
552     {
553       void* __p = atomic_fetch_sub_explicit(this, sizeof(_Tp) * __d, __m);
554       return static_cast<_Tp*>(__p);
555     }
556
557   // Convenience function definitions, atomic_flag.
558   inline bool
559   atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m)
560   { return __a->test_and_set(__m); }
561
562   inline void
563   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m)
564   { return __a->clear(__m); }
565
566
567   // Convenience function definitions, atomic_address.
568   inline bool
569   atomic_is_lock_free(const atomic_address* __a)
570   { return __a->is_lock_free(); }
571
572   inline void
573   atomic_store(atomic_address* __a, void* __v)
574   { __a->store(__v); }
575
576   inline void
577   atomic_store_explicit(atomic_address* __a, void* __v, memory_order __m)
578   { __a->store(__v, __m); }
579
580   inline void*
581   atomic_load(const atomic_address* __a)
582   { return __a->load(); }
583
584   inline void*
585   atomic_load_explicit(const atomic_address* __a, memory_order __m)
586   { return __a->load(__m); }
587
588   inline void*
589   atomic_exchange(atomic_address* __a, void* __v)
590   { return __a->exchange(__v); }
591
592   inline void*
593   atomic_exchange_explicit(atomic_address* __a, void* __v, memory_order __m)
594   { return __a->exchange(__v, __m); }
595
596   inline bool
597   atomic_compare_exchange_weak(atomic_address* __a, void** __v1, void* __v2)
598   {
599     return __a->compare_exchange_weak(*__v1, __v2, memory_order_seq_cst,
600                                       memory_order_seq_cst);
601   }
602
603   inline bool
604   atomic_compare_exchange_strong(atomic_address* __a,
605                                void** __v1, void* __v2)
606   {
607     return __a->compare_exchange_strong(*__v1, __v2, memory_order_seq_cst,
608                                       memory_order_seq_cst);
609   }
610
611   inline bool
612   atomic_compare_exchange_weak_explicit(atomic_address* __a,
613                                         void** __v1, void* __v2,
614                                         memory_order __m1, memory_order __m2)
615   { return __a->compare_exchange_weak(*__v1, __v2, __m1, __m2); }
616
617   inline bool
618   atomic_compare_exchange_strong_explicit(atomic_address* __a,
619                                           void** __v1, void* __v2,
620                                           memory_order __m1, memory_order __m2)
621   { return __a->compare_exchange_strong(*__v1, __v2, __m1, __m2); }
622
623   inline void*
624   atomic_fetch_add_explicit(atomic_address* __a, ptrdiff_t __d,
625                             memory_order __m)
626   { return __a->fetch_add(__d, __m); }
627
628   inline void*
629   atomic_fetch_add(atomic_address* __a, ptrdiff_t __d)
630   { return __a->fetch_add(__d); }
631
632   inline void*
633   atomic_fetch_sub_explicit(atomic_address* __a, ptrdiff_t __d,
634                             memory_order __m)
635   { return __a->fetch_sub(__d, __m); }
636
637   inline void*
638   atomic_fetch_sub(atomic_address* __a, ptrdiff_t __d)
639   { return __a->fetch_sub(__d); }
640
641
642   // Convenience function definitions, atomic_bool.
643   inline bool
644   atomic_is_lock_free(const atomic_bool* __a)
645   { return __a->is_lock_free(); }
646
647   inline void
648   atomic_store(atomic_bool* __a, bool __i)
649   { __a->store(__i); }
650
651   inline void
652   atomic_store_explicit(atomic_bool* __a, bool __i, memory_order __m)
653   { __a->store(__i, __m); }
654
655   inline bool
656   atomic_load(const atomic_bool* __a)
657   { return __a->load(); }
658
659   inline bool
660   atomic_load_explicit(const atomic_bool* __a, memory_order __m)
661   { return __a->load(__m); }
662
663   inline bool
664   atomic_exchange(atomic_bool* __a, bool __i)
665   { return __a->exchange(__i); }
666
667   inline bool
668   atomic_exchange_explicit(atomic_bool* __a, bool __i, memory_order __m)
669   { return __a->exchange(__i, __m); }
670
671   inline bool
672   atomic_compare_exchange_weak(atomic_bool* __a, bool* __i1, bool __i2)
673   {
674     return __a->compare_exchange_weak(*__i1, __i2, memory_order_seq_cst,
675                                       memory_order_seq_cst);
676   }
677
678   inline bool
679   atomic_compare_exchange_strong(atomic_bool* __a, bool* __i1, bool __i2)
680   {
681     return __a->compare_exchange_strong(*__i1, __i2, memory_order_seq_cst,
682                                         memory_order_seq_cst);
683   }
684
685   inline bool
686   atomic_compare_exchange_weak_explicit(atomic_bool* __a, bool* __i1,
687                                         bool __i2, memory_order __m1,
688                                         memory_order __m2)
689   { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
690
691   inline bool
692   atomic_compare_exchange_strong_explicit(atomic_bool* __a,
693                                           bool* __i1, bool __i2,
694                                           memory_order __m1, memory_order __m2)
695   { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
696
697
698
699   // Free standing functions. Template argument should be constricted
700   // to intergral types as specified in the standard.
701   template<typename _ITp>
702     inline void
703     atomic_store_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m)
704     { __a->store(__i, __m); }
705
706   template<typename _ITp>
707     inline _ITp
708     atomic_load_explicit(const __atomic_base<_ITp>* __a, memory_order __m)
709     { return __a->load(__m); }
710
711   template<typename _ITp>
712     inline _ITp
713     atomic_exchange_explicit(__atomic_base<_ITp>* __a, _ITp __i,
714                              memory_order __m)
715     { return __a->exchange(__i, __m); }
716
717   template<typename _ITp>
718     inline bool
719     atomic_compare_exchange_weak_explicit(__atomic_base<_ITp>* __a,
720                                           _ITp* __i1, _ITp __i2,
721                                           memory_order __m1, memory_order __m2)
722     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
723
724   template<typename _ITp>
725     inline bool
726     atomic_compare_exchange_strong_explicit(__atomic_base<_ITp>* __a,
727                                             _ITp* __i1, _ITp __i2,
728                                             memory_order __m1,
729                                             memory_order __m2)
730     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
731
732   template<typename _ITp>
733     inline _ITp
734     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
735                               memory_order __m)
736     { return __a->fetch_add(__i, __m); }
737
738   template<typename _ITp>
739     inline _ITp
740     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
741                               memory_order __m)
742     { return __a->fetch_sub(__i, __m); }
743
744   template<typename _ITp>
745     inline _ITp
746     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
747                               memory_order __m)
748     { return __a->fetch_and(__i, __m); }
749
750   template<typename _ITp>
751     inline _ITp
752     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
753                              memory_order __m)
754     { return __a->fetch_or(__i, __m); }
755
756   template<typename _ITp>
757     inline _ITp
758     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
759                               memory_order __m)
760     { return __a->fetch_xor(__i, __m); }
761
762   template<typename _ITp>
763     inline bool
764     atomic_is_lock_free(const __atomic_base<_ITp>* __a)
765     { return __a->is_lock_free(); }
766
767   template<typename _ITp>
768     inline void
769     atomic_store(__atomic_base<_ITp>* __a, _ITp __i)
770     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
771
772   template<typename _ITp>
773     inline _ITp
774     atomic_load(const __atomic_base<_ITp>* __a)
775     { return atomic_load_explicit(__a, memory_order_seq_cst); }
776
777   template<typename _ITp>
778     inline _ITp
779     atomic_exchange(__atomic_base<_ITp>* __a, _ITp __i)
780     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
781
782   template<typename _ITp>
783     inline bool
784     atomic_compare_exchange_weak(__atomic_base<_ITp>* __a,
785                                  _ITp* __i1, _ITp __i2)
786     {
787       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
788                                                    memory_order_seq_cst,
789                                                    memory_order_seq_cst);
790     }
791
792   template<typename _ITp>
793     inline bool
794     atomic_compare_exchange_strong(__atomic_base<_ITp>* __a,
795                                    _ITp* __i1, _ITp __i2)
796     {
797       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
798                                                      memory_order_seq_cst,
799                                                      memory_order_seq_cst);
800     }
801
802   template<typename _ITp>
803     inline _ITp
804     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i)
805     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
806
807   template<typename _ITp>
808     inline _ITp
809     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i)
810     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
811
812   template<typename _ITp>
813     inline _ITp
814     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i)
815     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
816
817   template<typename _ITp>
818     inline _ITp
819     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i)
820     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
821
822   template<typename _ITp>
823     inline _ITp
824     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i)
825     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
826
827   // @} group atomics
828
829 _GLIBCXX_END_NAMESPACE
830
831 #endif