1
+ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
1
2
/*
2
3
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3
4
* University Research and Technology
11
12
* All rights reserved.
12
13
* Copyright (c) 2010 IBM Corporation. All rights reserved.
13
14
* Copyright (c) 2010 ARM ltd. All rights reserved.
15
+ * Copyright (c) 2017 Los Alamos National Security, LLC. All rights
16
+ * reserved.
14
17
* $COPYRIGHT$
15
18
*
16
19
* Additional copyrights may follow
@@ -104,12 +107,12 @@ void opal_atomic_isync(void)
104
107
105
108
#if (OPAL_GCC_INLINE_ASSEMBLY && (OPAL_ASM_ARM_VERSION >= 6 ))
106
109
107
- #define OPAL_HAVE_ATOMIC_CMPSET_32 1
110
+ #define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 1
108
111
#define OPAL_HAVE_ATOMIC_MATH_32 1
109
- static inline bool opal_atomic_bool_cmpset_32 (volatile int32_t * addr ,
110
- int32_t oldval , int32_t newval )
112
+ static inline bool opal_atomic_compare_exchange_strong_32 (volatile int32_t * addr , int32_t * oldval , int32_t newval )
111
113
{
112
- int32_t ret , tmp ;
114
+ int32_t prev , tmp ;
115
+ bool ret ;
113
116
114
117
__asm__ __volatile__ (
115
118
"1: ldrex %0, [%2] \n"
@@ -120,87 +123,86 @@ static inline bool opal_atomic_bool_cmpset_32(volatile int32_t *addr,
120
123
" bne 1b \n"
121
124
"2: \n"
122
125
123
- : "=&r" (ret ), "=&r" (tmp )
124
- : "r" (addr ), "r" (oldval ), "r" (newval )
126
+ : "=&r" (prev ), "=&r" (tmp )
127
+ : "r" (addr ), "r" (* oldval ), "r" (newval )
125
128
: "cc" , "memory" );
126
129
127
- return (ret == oldval );
130
+ ret = (prev == * oldval );
131
+ * oldval = prev ;
132
+ return ret ;
128
133
}
129
134
130
135
/* these two functions aren't inlined in the non-gcc case because then
131
136
there would be two function calls (since neither cmpset_32 nor
132
137
atomic_?mb can be inlined). Instead, we "inline" them by hand in
133
138
the assembly, meaning there is one function call overhead instead
134
139
of two */
135
- static inline bool opal_atomic_bool_cmpset_acq_32 (volatile int32_t * addr ,
136
- int32_t oldval , int32_t newval )
140
+ static inline bool opal_atomic_compare_exchange_strong_acq_32 (volatile int32_t * addr , int32_t * oldval , int32_t newval )
137
141
{
138
142
bool rc ;
139
143
140
- rc = opal_atomic_bool_cmpset_32 (addr , oldval , newval );
144
+ rc = opal_atomic_compare_exchange_strong_32 (addr , oldval , newval );
141
145
opal_atomic_rmb ();
142
146
143
147
return rc ;
144
148
}
145
149
146
150
147
- static inline bool opal_atomic_bool_cmpset_rel_32 (volatile int32_t * addr ,
148
- int32_t oldval , int32_t newval )
151
+ static inline bool opal_atomic_compare_exchange_strong_rel_32 (volatile int32_t * addr , int32_t * oldval , int32_t newval )
149
152
{
150
153
opal_atomic_wmb ();
151
- return opal_atomic_bool_cmpset_32 (addr , oldval , newval );
154
+ return opal_atomic_compare_exchange_strong_32 (addr , oldval , newval );
152
155
}
153
156
154
157
#if (OPAL_ASM_SUPPORT_64BIT == 1 )
155
158
156
- #define OPAL_HAVE_ATOMIC_CMPSET_64 1
157
- static inline bool opal_atomic_bool_cmpset_64 (volatile int64_t * addr ,
158
- int64_t oldval , int64_t newval )
159
+ #define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64 1
160
+ static inline bool opal_atomic_compare_exchange_strong_64 (volatile int64_t * addr , int64_t * oldval , int64_t newval )
159
161
{
160
- int64_t ret ;
161
- int tmp ;
162
-
163
-
164
- __asm__ __volatile__ (
165
- "1: ldrexd %0, %H0, [%2] \n"
166
- " cmp %0, %3 \n"
167
- " it eq \n"
168
- " cmpeq %H0, %H3 \n"
169
- " bne 2f \n"
170
- " strexd %1, %4, %H4, [%2] \n"
171
- " cmp %1, #0 \n"
172
- " bne 1b \n"
173
- "2: \n"
174
-
175
- : "=&r" (ret ), "=&r" (tmp )
176
- : "r" (addr ), "r" (oldval ), "r" (newval )
177
- : "cc" , "memory" );
178
-
179
- return (ret == oldval );
162
+ int64_t prev ;
163
+ int tmp ;
164
+ bool ret ;
165
+
166
+ __asm__ __volatile__ (
167
+ "1: ldrexd %0, %H0, [%2] \n"
168
+ " cmp %0, %3 \n"
169
+ " it eq \n"
170
+ " cmpeq %H0, %H3 \n"
171
+ " bne 2f \n"
172
+ " strexd %1, %4, %H4, [%2] \n"
173
+ " cmp %1, #0 \n"
174
+ " bne 1b \n"
175
+ "2: \n"
176
+
177
+ : "=&r" (prev ), "=&r" (tmp )
178
+ : "r" (addr ), "r" (* oldval ), "r" (newval )
179
+ : "cc" , "memory" );
180
+
181
+ ret = (prev == * oldval );
182
+ * oldval = prev ;
183
+ return ret ;
180
184
}
181
185
182
186
/* these two functions aren't inlined in the non-gcc case because then
183
187
there would be two function calls (since neither cmpset_64 nor
184
188
atomic_?mb can be inlined). Instead, we "inline" them by hand in
185
189
the assembly, meaning there is one function call overhead instead
186
190
of two */
187
- static inline bool opal_atomic_bool_cmpset_acq_64 (volatile int64_t * addr ,
188
- int64_t oldval , int64_t newval )
191
+ static inline bool opal_atomic_compare_exchange_strong_acq_64 (volatile int64_t * addr , int64_t * oldval , int64_t newval )
189
192
{
190
193
bool rc ;
191
194
192
- rc = opal_atomic_bool_cmpset_64 (addr , oldval , newval );
195
+ rc = opal_atomic_compare_exchange_strong_64 (addr , oldval , newval );
193
196
opal_atomic_rmb ();
194
197
195
198
return rc ;
196
199
}
197
200
198
201
199
- static inline bool opal_atomic_bool_cmpset_rel_64 (volatile int64_t * addr ,
200
- int64_t oldval , int64_t newval )
202
+ static inline bool opal_atomic_compare_exchange_strong_rel_64 (volatile int64_t * addr , int64_t * oldval , int64_t newval )
201
203
{
202
204
opal_atomic_wmb ();
203
- return opal_atomic_bool_cmpset_64 (addr , oldval , newval );
205
+ return opal_atomic_compare_exchange_strong_64 (addr , oldval , newval );
204
206
}
205
207
206
208
#endif
@@ -247,30 +249,6 @@ static inline int32_t opal_atomic_sub_32(volatile int32_t* v, int dec)
247
249
return t ;
248
250
}
249
251
250
- #else /* OPAL_ASM_ARM_VERSION <=5 or no GCC inline assembly */
251
-
252
- #define OPAL_HAVE_ATOMIC_CMPSET_32 1
253
- #define __kuser_cmpxchg (*((int (*)(int, int, volatile int*))(0xffff0fc0)))
254
- static inline bool opal_atomic_bool_cmpset_32 (volatile int32_t * addr ,
255
- int32_t oldval , int32_t newval )
256
- {
257
- return !(__kuser_cmpxchg (oldval , newval , addr ));
258
- }
259
-
260
- static inline bool opal_atomic_bool_cmpset_acq_32 (volatile int32_t * addr ,
261
- int32_t oldval , int32_t newval )
262
- {
263
- /* kernel function includes all necessary memory barriers */
264
- return opal_atomic_bool_cmpset_32 (addr , oldval , newval );
265
- }
266
-
267
- static inline bool opal_atomic_bool_cmpset_rel_32 (volatile int32_t * addr ,
268
- int32_t oldval , int32_t newval )
269
- {
270
- /* kernel function includes all necessary memory barriers */
271
- return opal_atomic_bool_cmpset_32 (addr , oldval , newval );
272
- }
273
-
274
252
#endif
275
253
276
254
#endif /* ! OPAL_SYS_ARCH_ATOMIC_H */
0 commit comments