OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

atomic.h
1 /*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2010 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserverd.
13 * $COPYRIGHT$
14 *
15 * Additional copyrights may follow
16 *
17 * $HEADER$
18 */
19 #ifndef OMPI_SYS_ARCH_ATOMIC_H
20 #define OMPI_SYS_ARCH_ATOMIC_H 1
21
22 /*
23 * On amd64, we use cmpxchg.
24 */
25
26
27 #if OPAL_WANT_SMP_LOCKS
28 #define SMPLOCK "lock; "
29 #define MB() __asm__ __volatile__("": : :"memory")
30 #else
31 #define SMPLOCK
32 #define MB()
33 #endif
34
35
36 /**********************************************************************
37 *
38 * Define constants for AMD64 / x86_64 / EM64T / ...
39 *
40 *********************************************************************/
41 #define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
42
43 #define OPAL_HAVE_ATOMIC_CMPSET_32 1
44
45 #define OPAL_HAVE_ATOMIC_CMPSET_64 1
46
47 #define OPAL_HAVE_ATOMIC_SWAP_32 1
48
49 #define OPAL_HAVE_ATOMIC_SWAP_64 1
50
51 /**********************************************************************
52 *
53 * Memory Barriers
54 *
55 *********************************************************************/
56 #if OMPI_GCC_INLINE_ASSEMBLY
57
58 static inline void opal_atomic_mb(void)
59 {
60 MB();
61 }
62
63
64 static inline void opal_atomic_rmb(void)
65 {
66 MB();
67 }
68
69
70 static inline void opal_atomic_wmb(void)
71 {
72 MB();
73 }
74
75 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
76
77
78 /**********************************************************************
79 *
80 * Atomic math operations
81 *
82 *********************************************************************/
83 #if OMPI_GCC_INLINE_ASSEMBLY
84
85 static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
86 int32_t oldval, int32_t newval)
87 {
88 unsigned char ret;
89 __asm__ __volatile__ (
90 SMPLOCK "cmpxchgl %3,%2 \n\t"
91 "sete %0 \n\t"
92 : "=qm" (ret), "+a" (oldval), "+m" (*addr)
93 : "q"(newval)
94 : "memory", "cc");
95
96 return (int)ret;
97 }
98
99 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
100
101 #define opal_atomic_cmpset_acq_32 opal_atomic_cmpset_32
102 #define opal_atomic_cmpset_rel_32 opal_atomic_cmpset_32
103
104 #if OMPI_GCC_INLINE_ASSEMBLY
105
106 static inline int opal_atomic_cmpset_64( volatile int64_t *addr,
107 int64_t oldval, int64_t newval)
108 {
109 unsigned char ret;
110 __asm__ __volatile__ (
111 SMPLOCK "cmpxchgq %3,%2 \n\t"
112 "sete %0 \n\t"
113 : "=qm" (ret), "+a" (oldval), "+m" (*((volatile long*)addr))
114 : "q"(newval)
115 : "memory", "cc"
116 );
117
118 return (int)ret;
119 }
120
121 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
122
123 #define opal_atomic_cmpset_acq_64 opal_atomic_cmpset_64
124 #define opal_atomic_cmpset_rel_64 opal_atomic_cmpset_64
125
126 #if OMPI_GCC_INLINE_ASSEMBLY
127
128 static inline int32_t opal_atomic_swap_32( volatile int32_t *addr,
129 int32_t newval)
130 {
131 int32_t oldval;
132
133 __asm__ __volatile__("xchg %1, %0" :
134 "=r" (oldval), "=m" (*addr) :
135 "0" (newval), "m" (*addr) :
136 "memory");
137 return oldval;
138 }
139
140 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
141
142 #if OMPI_GCC_INLINE_ASSEMBLY
143
144 static inline int64_t opal_atomic_swap_64( volatile int64_t *addr,
145 int64_t newval)
146 {
147 int64_t oldval;
148
149 __asm__ __volatile__("xchgq %1, %0" :
150 "=r" (oldval) :
151 "m" (*addr), "0" (newval) :
152 "memory");
153 return oldval;
154 }
155
156 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
157
158
159
160 #if OMPI_GCC_INLINE_ASSEMBLY
161
162 #define OPAL_HAVE_ATOMIC_MATH_32 1
163 #define OPAL_HAVE_ATOMIC_MATH_64 1
164
165 #define OPAL_HAVE_ATOMIC_ADD_32 1
166
167 /**
168 * atomic_add - add integer to atomic variable
169 * @i: integer value to add
170 * @v: pointer of type int
171 *
172 * Atomically adds @i to @v.
173 */
174 static inline int32_t opal_atomic_add_32(volatile int32_t* v, int i)
175 {
176 int ret = i;
177 __asm__ __volatile__(
178 SMPLOCK "xaddl %1,%0"
179 :"=m" (*v), "+r" (ret)
180 :"m" (*v)
181 :"memory", "cc"
182 );
183 return (ret+i);
184 }
185
186 #define OPAL_HAVE_ATOMIC_ADD_64 1
187
188 /**
189 * atomic_add - add integer to atomic variable
190 * @i: integer value to add
191 * @v: pointer of type int
192 *
193 * Atomically adds @i to @v.
194 */
195 static inline int64_t opal_atomic_add_64(volatile int64_t* v, int64_t i)
196 {
197 int64_t ret = i;
198 __asm__ __volatile__(
199 SMPLOCK "xaddq %1,%0"
200 :"=m" (*v), "+r" (ret)
201 :"m" (*v)
202 :"memory", "cc"
203 );
204 return (ret+i);
205 }
206
207 #define OPAL_HAVE_ATOMIC_SUB_32 1
208
209 /**
210 * atomic_sub - subtract the atomic variable
211 * @i: integer value to subtract
212 * @v: pointer of type int
213 *
214 * Atomically subtracts @i from @v.
215 */
216 static inline int32_t opal_atomic_sub_32(volatile int32_t* v, int i)
217 {
218 int ret = -i;
219 __asm__ __volatile__(
220 SMPLOCK "xaddl %1,%0"
221 :"=m" (*v), "+r" (ret)
222 :"m" (*v)
223 :"memory", "cc"
224 );
225 return (ret-i);
226 }
227
228 #define OPAL_HAVE_ATOMIC_SUB_64 1
229
230 /**
231 * atomic_sub - subtract the atomic variable
232 * @i: integer value to subtract
233 * @v: pointer of type int
234 *
235 * Atomically subtracts @i from @v.
236 */
237 static inline int64_t opal_atomic_sub_64(volatile int64_t* v, int64_t i)
238 {
239 int64_t ret = -i;
240 __asm__ __volatile__(
241 SMPLOCK "xaddq %1,%0"
242 :"=m" (*v), "+r" (ret)
243 :"m" (*v)
244 :"memory", "cc"
245 );
246 return (ret-i);
247 }
248
249 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
250
251 #endif /* ! OMPI_SYS_ARCH_ATOMIC_H */
opal_atomic_rmb
void opal_atomic_rmb(void)
Read memory barrier.
opal_atomic_mb
void opal_atomic_mb(void)
Memory barrier.
opal_atomic_wmb
void opal_atomic_wmb(void)
Write memory barrier.