linuxsampler 2.3.1
lsatomic.h
Go to the documentation of this file.
1/***************************************************************************
2 * *
3 * Copyright (C) 2008-2013 Andreas Persson *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
18 * MA 02110-1301 USA *
19 ***************************************************************************/
20
21#ifndef LSATOMIC_H
22#define LSATOMIC_H
23
82// if C++11 and gcc 4.7 or later is used, then use the standard
83// implementation
84#if __cplusplus >= 201103L && \
85 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
86
87#include <atomic>
88
89namespace LinuxSampler {
90 using std::memory_order_relaxed;
91 using std::memory_order_acquire;
92 using std::memory_order_release;
93 using std::memory_order_seq_cst;
94 using std::atomic_thread_fence;
95 using std::atomic;
96}
97
98#else
99
100
101namespace LinuxSampler {
106
108 switch (order) {
110 break;
111
114#ifdef _ARCH_PPC64
115 asm volatile("lwsync" : : : "memory");
116#elif defined(_ARCH_PPC)
117 asm volatile("sync" : : : "memory");
118#elif defined(__ARM_ARCH_7A__)
119 asm volatile("dmb" : : : "memory");
120#else
121 asm volatile("" : : : "memory");
122#endif
123 break;
124
126#ifdef _ARCH_PPC
127 asm volatile("sync" : : : "memory");
128#elif defined(__i386__)
129 asm volatile("lock; addl $0,0(%%esp)" : : : "memory");
130#elif defined(__x86_64__)
131 asm volatile("mfence" : : : "memory");
132#elif defined(__ARM_ARCH_7A__)
133 asm volatile("dmb" : : : "memory");
134#else
135 asm volatile("" : : : "memory");
136#endif
137 break;
138 }
139 }
140
141 template<typename T> class atomic;
142 template<> class atomic<int> { // int is the only implemented type
143 public:
144 atomic() { }
145 explicit atomic(int m) : f(m) { }
146 int load(memory_order order = memory_order_seq_cst) const volatile {
147 int m;
148 switch (order) {
150 m = f;
151 break;
152
154 case memory_order_release: // (invalid)
155#ifdef _ARCH_PPC
157#endif
158 // fall-through
159
161#ifdef _ARCH_PPC
162 // PPC load-acquire: artificial dependency + isync
163 asm volatile(
164 "lwz%U1%X1 %0,%1\n\t"
165 "cmpw %0,%0\n\t"
166 "bne- 1f\n\t"
167 "1: isync"
168 : "=r" (m)
169 : "m" (f)
170 : "memory", "cr0");
171#else
172 m = f;
174#endif
175 break;
176 }
177 return m;
178 }
179
180 void store(int m, memory_order order = memory_order_seq_cst) volatile {
181 switch (order) {
183 f = m;
184 break;
185
188 f = m;
189 break;
190
192 case memory_order_acquire: // (invalid)
193#ifdef _ARCH_PPC
195 f = m;
196#else
198 f = m;
200#endif
201 break;
202 }
203 }
204 private:
205 int f;
206 atomic(const atomic&); // not allowed
207 atomic& operator=(const atomic&); // not allowed
208 };
209}
210#endif
211#endif
int load(memory_order order=memory_order_seq_cst) const volatile
Definition lsatomic.h:146
void store(int m, memory_order order=memory_order_seq_cst) volatile
Definition lsatomic.h:180
@ memory_order_acquire
Definition lsatomic.h:103
@ memory_order_relaxed
Definition lsatomic.h:103
@ memory_order_release
Definition lsatomic.h:104
@ memory_order_seq_cst
Definition lsatomic.h:104
void atomic_thread_fence(memory_order order)
Definition lsatomic.h:107