xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/ext/atomicity.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino // Support for atomic operations -*- C++ -*-
2*e4b17023SJohn Marino 
3*e4b17023SJohn Marino // Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012
4*e4b17023SJohn Marino // Free Software Foundation, Inc.
5*e4b17023SJohn Marino //
6*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
7*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
8*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
9*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino // any later version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*e4b17023SJohn Marino // GNU General Public License for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
18*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
19*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
22*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
23*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
25*e4b17023SJohn Marino 
26*e4b17023SJohn Marino /** @file ext/atomicity.h
27*e4b17023SJohn Marino  *  This file is a GNU extension to the Standard C++ Library.
28*e4b17023SJohn Marino  */
29*e4b17023SJohn Marino 
30*e4b17023SJohn Marino #ifndef _GLIBCXX_ATOMICITY_H
31*e4b17023SJohn Marino #define _GLIBCXX_ATOMICITY_H	1
32*e4b17023SJohn Marino 
33*e4b17023SJohn Marino #include <bits/c++config.h>
34*e4b17023SJohn Marino #include <bits/gthr.h>
35*e4b17023SJohn Marino #include <bits/atomic_word.h>
36*e4b17023SJohn Marino 
_GLIBCXX_VISIBILITY(default)37*e4b17023SJohn Marino namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
38*e4b17023SJohn Marino {
39*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
40*e4b17023SJohn Marino 
41*e4b17023SJohn Marino   // Functions for portable atomic access.
42*e4b17023SJohn Marino   // To abstract locking primitives across all thread policies, use:
43*e4b17023SJohn Marino   // __exchange_and_add_dispatch
44*e4b17023SJohn Marino   // __atomic_add_dispatch
45*e4b17023SJohn Marino #ifdef _GLIBCXX_ATOMIC_BUILTINS
46*e4b17023SJohn Marino   static inline _Atomic_word
47*e4b17023SJohn Marino   __exchange_and_add(volatile _Atomic_word* __mem, int __val)
48*e4b17023SJohn Marino   { return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
49*e4b17023SJohn Marino 
50*e4b17023SJohn Marino   static inline void
51*e4b17023SJohn Marino   __atomic_add(volatile _Atomic_word* __mem, int __val)
52*e4b17023SJohn Marino   { __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
53*e4b17023SJohn Marino #else
54*e4b17023SJohn Marino   _Atomic_word
55*e4b17023SJohn Marino   __attribute__ ((__unused__))
56*e4b17023SJohn Marino   __exchange_and_add(volatile _Atomic_word*, int) throw ();
57*e4b17023SJohn Marino 
58*e4b17023SJohn Marino   void
59*e4b17023SJohn Marino   __attribute__ ((__unused__))
60*e4b17023SJohn Marino   __atomic_add(volatile _Atomic_word*, int) throw ();
61*e4b17023SJohn Marino #endif
62*e4b17023SJohn Marino 
63*e4b17023SJohn Marino   static inline _Atomic_word
64*e4b17023SJohn Marino   __exchange_and_add_single(_Atomic_word* __mem, int __val)
65*e4b17023SJohn Marino   {
66*e4b17023SJohn Marino     _Atomic_word __result = *__mem;
67*e4b17023SJohn Marino     *__mem += __val;
68*e4b17023SJohn Marino     return __result;
69*e4b17023SJohn Marino   }
70*e4b17023SJohn Marino 
71*e4b17023SJohn Marino   static inline void
72*e4b17023SJohn Marino   __atomic_add_single(_Atomic_word* __mem, int __val)
73*e4b17023SJohn Marino   { *__mem += __val; }
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino   static inline _Atomic_word
76*e4b17023SJohn Marino   __attribute__ ((__unused__))
77*e4b17023SJohn Marino   __exchange_and_add_dispatch(_Atomic_word* __mem, int __val)
78*e4b17023SJohn Marino   {
79*e4b17023SJohn Marino #ifdef __GTHREADS
80*e4b17023SJohn Marino     if (__gthread_active_p())
81*e4b17023SJohn Marino       return __exchange_and_add(__mem, __val);
82*e4b17023SJohn Marino     else
83*e4b17023SJohn Marino       return __exchange_and_add_single(__mem, __val);
84*e4b17023SJohn Marino #else
85*e4b17023SJohn Marino     return __exchange_and_add_single(__mem, __val);
86*e4b17023SJohn Marino #endif
87*e4b17023SJohn Marino   }
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino   static inline void
90*e4b17023SJohn Marino   __attribute__ ((__unused__))
91*e4b17023SJohn Marino   __atomic_add_dispatch(_Atomic_word* __mem, int __val)
92*e4b17023SJohn Marino   {
93*e4b17023SJohn Marino #ifdef __GTHREADS
94*e4b17023SJohn Marino     if (__gthread_active_p())
95*e4b17023SJohn Marino       __atomic_add(__mem, __val);
96*e4b17023SJohn Marino     else
97*e4b17023SJohn Marino       __atomic_add_single(__mem, __val);
98*e4b17023SJohn Marino #else
99*e4b17023SJohn Marino     __atomic_add_single(__mem, __val);
100*e4b17023SJohn Marino #endif
101*e4b17023SJohn Marino   }
102*e4b17023SJohn Marino 
103*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
104*e4b17023SJohn Marino } // namespace
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino // Even if the CPU doesn't need a memory barrier, we need to ensure
107*e4b17023SJohn Marino // that the compiler doesn't reorder memory accesses across the
108*e4b17023SJohn Marino // barriers.
109*e4b17023SJohn Marino #ifndef _GLIBCXX_READ_MEM_BARRIER
110*e4b17023SJohn Marino #define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("":::"memory")
111*e4b17023SJohn Marino #endif
112*e4b17023SJohn Marino #ifndef _GLIBCXX_WRITE_MEM_BARRIER
113*e4b17023SJohn Marino #define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("":::"memory")
114*e4b17023SJohn Marino #endif
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino #endif
117