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-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 (c) 2007 Sun Microsystems, Inc. All rights reserverd.
13 * $COPYRIGHT$
14 *
15 * Additional copyrights may follow
16 *
17 * $HEADER$
18 */
19
20 #ifndef OMPI_SYS_ARCH_ATOMIC_H
21 #define OMPI_SYS_ARCH_ATOMIC_H 1
22
23 /*
24 * On sparc v9, use casa and casxa (compare and swap) instructions.
25 */
26
27 #define ASI_P "0x80"
28
29 #if OPAL_WANT_SMP_LOCKS
30 #define MEMBAR(type) __asm__ __volatile__ ("membar " type : : : "memory")
31 #else
32 #define MEMBAR(type)
33 #endif
34
35
36 /**********************************************************************
37 *
38 * Define constants for Sparc v9 (Ultra Sparc)
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
48 /**********************************************************************
49 *
50 * Memory Barriers
51 *
52 *********************************************************************/
53 #if OMPI_GCC_INLINE_ASSEMBLY
54
55 static inline void opal_atomic_mb(void)
56 {
57 MEMBAR("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad");
58 }
59
60
61 static inline void opal_atomic_rmb(void)
62 {
63 MEMBAR("#LoadLoad");
64 }
65
66
67 static inline void opal_atomic_wmb(void)
68 {
69 MEMBAR("#StoreStore");
70 }
71
72 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
73
74
75 /**********************************************************************
76 *
77 * Atomic math operations
78 *
79 *********************************************************************/
80 #if OMPI_GCC_INLINE_ASSEMBLY
81
82 static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
83 int32_t oldval, int32_t newval)
84 {
85 /* casa [reg(rs1)] %asi, reg(rs2), reg(rd)
86 *
87 * if (*(reg(rs1)) == reg(rs1) )
88 * swap reg(rd), *(reg(rs1))
89 * else
90 * reg(rd) = *(reg(rs1))
91 */
92
93 int32_t ret = newval;
94
95 __asm__ __volatile__("casa [%1] " ASI_P ", %2, %0"
96 : "+r" (ret)
97 : "r" (addr), "r" (oldval));
98 return (ret == oldval);
99 }
100
101
102 static inline int opal_atomic_cmpset_acq_32( volatile int32_t *addr,
103 int32_t oldval, int32_t newval)
104 {
105 int rc;
106
107 rc = opal_atomic_cmpset_32(addr, oldval, newval);
108 opal_atomic_rmb();
109
110 return rc;
111 }
112
113
114 static inline int opal_atomic_cmpset_rel_32( volatile int32_t *addr,
115 int32_t oldval, int32_t newval)
116 {
117 opal_atomic_wmb();
118 return opal_atomic_cmpset_32(addr, oldval, newval);
119 }
120
121
122 #if OPAL_ASSEMBLY_ARCH == OMPI_SPARCV9_64
123
124 static inline int opal_atomic_cmpset_64( volatile int64_t *addr,
125 int64_t oldval, int64_t newval)
126 {
127 /* casa [reg(rs1)] %asi, reg(rs2), reg(rd)
128 *
129 * if (*(reg(rs1)) == reg(rs1) )
130 * swap reg(rd), *(reg(rs1))
131 * else
132 * reg(rd) = *(reg(rs1))
133 */
134 int64_t ret = newval;
135
136 __asm__ __volatile__("casxa [%1] " ASI_P ", %2, %0"
137 : "+r" (ret)
138 : "r" (addr), "r" (oldval));
139 return (ret == oldval);
140 }
141
142 #else /* OPAL_ASSEMBLY_ARCH == OMPI_SPARCV9_64 */
143
144 static inline int opal_atomic_cmpset_64( volatile int64_t *addr,
145 int64_t oldval, int64_t newval)
146 {
147 /* casa [reg(rs1)] %asi, reg(rs2), reg(rd)
148 *
149 * if (*(reg(rs1)) == reg(rs1) )
150 * swap reg(rd), *(reg(rs1))
151 * else
152 * reg(rd) = *(reg(rs1))
153 *
154 */
155 long long ret = newval;
156
157 __asm__ __volatile__(
158 "ldx %0, %%g1 \n\t" /* g1 = ret */
159 "ldx %2, %%g2 \n\t" /* g2 = oldval */
160 "casxa [%1] " ASI_P ", %%g2, %%g1 \n\t"
161 "stx %%g1, %0 \n"
162 : "+m"(ret)
163 : "r"(addr), "m"(oldval)
164 : "%g1", "%g2"
165 );
166
167 return (ret == oldval);
168 }
169
170 #endif /* OPAL_ASSEMBLY_ARCH == OMPI_SPARCV9_64 */
171
172 static inline int opal_atomic_cmpset_acq_64( volatile int64_t *addr,
173 int64_t oldval, int64_t newval)
174 {
175 int rc;
176
177 rc = opal_atomic_cmpset_64(addr, oldval, newval);
178 opal_atomic_rmb();
179
180 return rc;
181 }
182
183
184 static inline int opal_atomic_cmpset_rel_64( volatile int64_t *addr,
185 int64_t oldval, int64_t newval)
186 {
187 opal_atomic_wmb();
188 return opal_atomic_cmpset_64(addr, oldval, newval);
189 }
190
191 #endif /* OMPI_GCC_INLINE_ASSEMBLY */
192
193
194 #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.