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-2005 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$
13  *
14  * Additional copyrights may follow
15  *
16  * $HEADER$
17  */
18 
19 #ifndef OMPI_SYS_ARCH_ATOMIC_H
20 #define OMPI_SYS_ARCH_ATOMIC_H 1
21 
22 /*
23  * On alpha, everything is load-locked, store-conditional...
24  */
25 
26 #if OPAL_WANT_SMP_LOCKS
27 
28 #define MB() __asm__ __volatile__ ("mb");
29 #define RMB() __asm__ __volatile__ ("mb");
30 #define WMB() __asm__ __volatile__ ("wmb");
31 
32 #else
33 
34 #define MB()
35 #define RMB()
36 #define WMB()
37 
38 #endif
39 
40 
41 /**********************************************************************
42  *
43  * Define constants for PowerPC 32
44  *
45  *********************************************************************/
46 #define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
47 
48 #define OPAL_HAVE_ATOMIC_CMPSET_32 1
49 
50 #define OPAL_HAVE_ATOMIC_CMPSET_64 1
51 
52 
53 /**********************************************************************
54  *
55  * Memory Barriers
56  *
57  *********************************************************************/
58 #if OMPI_GCC_INLINE_ASSEMBLY
59 
60 static inline void opal_atomic_mb(void)
61 {
62  MB();
63 }
64 
65 
66 static inline void opal_atomic_rmb(void)
67 {
68  RMB();
69 }
70 
71 
72 static inline void opal_atomic_wmb(void)
73 {
74  WMB();
75 }
76 
77 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
78 
79 
80 /**********************************************************************
81  *
82  * Atomic math operations
83  *
84  *********************************************************************/
85 #if OMPI_GCC_INLINE_ASSEMBLY
86 
87 static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
88  int32_t oldval, int32_t newval)
89 {
90  int32_t ret;
91 
92  __asm __volatile__ (
93  "1: ldl_l %0, %1 \n\t"
94  "cmpeq %0, %2, %0 \n\t"
95  "beq %0, 2f \n\t"
96  "mov %3, %0 \n\t"
97  "stl_c %0, %1 \n\t"
98  "beq %0, 1b \n\t"
99  "jmp 3f \n"
100  "2: mov $31, %0 \n"
101  "3: \n"
102  : "=&r" (ret), "+m" (*addr)
103  : "r" (oldval), "r" (newval)
104  : "memory");
105 
106  return ret;
107 }
108 
109 
110 static inline int opal_atomic_cmpset_acq_32(volatile int32_t *addr,
111  int32_t oldval,
112  int32_t newval)
113 {
114  int rc;
115 
116  rc = opal_atomic_cmpset_32(addr, oldval, newval);
117  opal_atomic_rmb();
118 
119  return rc;
120 }
121 
122 
123 static inline int opal_atomic_cmpset_rel_32(volatile int32_t *addr,
124  int32_t oldval,
125  int32_t newval)
126 {
127  opal_atomic_wmb();
128  return opal_atomic_cmpset_32(addr, oldval, newval);
129 }
130 
131 
132 static inline int opal_atomic_cmpset_64( volatile int64_t *addr,
133  int64_t oldval, int64_t newval)
134 {
135  int32_t ret;
136 
137  __asm__ __volatile__ (
138  "1: ldq_l %0, %1 \n\t"
139  "cmpeq %0, %2, %0 \n\t"
140  "beq %0, 2f \n\t"
141  "mov %3, %0 \n\t"
142  "stq_c %0, %1 \n\t"
143  "beq %0, 1b \n\t"
144  "jmp 3f \n"
145  "2: mov $31, %0 \n"
146  "3: \n"
147  : "=&r" (ret), "+m" (*addr)
148  : "r" (oldval), "r" (newval)
149  : "memory");
150 
151  return ret;
152 }
153 
154 
155 static inline int opal_atomic_cmpset_acq_64(volatile int64_t *addr,
156  int64_t oldval,
157  int64_t newval)
158 {
159  int rc;
160 
161  rc = opal_atomic_cmpset_64(addr, oldval, newval);
162  opal_atomic_rmb();
163 
164  return rc;
165 }
166 
167 
168 static inline int opal_atomic_cmpset_rel_64(volatile int64_t *addr,
169  int64_t oldval,
170  int64_t newval)
171 {
172  opal_atomic_wmb();
173  return opal_atomic_cmpset_64(addr, oldval, newval);
174 }
175 
176 
177 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
178 
179 
180 #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.