OpenMPI  0.1.1
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 */
void opal_atomic_rmb(void)
Read memory barrier.
void opal_atomic_mb(void)
Memory barrier.
void opal_atomic_wmb(void)
Write memory barrier.