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