Browse code

- added cmpxchg

Andrei Pelinescu-Onciul authored on 08/05/2007 08:25:37
Showing 1 changed files
... ...
@@ -42,6 +42,7 @@
42 42
  * History:
43 43
  * --------
44 44
  *  2006-03-08  created by andrei
45
+ *  2007-05-07  added cmpxchg (andrei)
45 46
  */
46 47
 
47 48
 #ifndef _atomic_x86_h
... ...
@@ -165,6 +166,24 @@
165 166
 		return ret; \
166 167
 	}
167 168
 
169
+/* returns a value, 3 params (var, old, new)
170
+ * The returned value is the value before the xchg:
171
+ *  if ret!=old => cmpxchg failed and ret is var's value
172
+ *  else  => success and new_v is var's new value */
173
+#define ATOMIC_FUNC_CMPXCHG(NAME, OP, P_TYPE, RET_TYPE) \
174
+	inline static RET_TYPE atomic_##NAME##_##P_TYPE(volatile P_TYPE* var, \
175
+													P_TYPE old, P_TYPE new_v)\
176
+	{ \
177
+		P_TYPE ret; \
178
+		asm volatile( \
179
+				__LOCK_PREF " " OP "\n\t" \
180
+				: "=a"(ret), "=m" (*var) :\
181
+					"r"(new_v), "m"(*var), "0"(old):\
182
+					"cc", "memory" \
183
+				); \
184
+		return ret; \
185
+	}
186
+
168 187
 ATOMIC_FUNC_DECL1(inc, "incl %0", int)
169 188
 ATOMIC_FUNC_DECL1(dec, "decl %0", int)
170 189
 ATOMIC_FUNC_DECL2(and, "andl %1, %0", int)
... ...
@@ -172,6 +191,7 @@ ATOMIC_FUNC_DECL2(or,  "orl %1, %0", int)
172 191
 ATOMIC_FUNC_TEST(inc_and_test, "incl %0", int, int)
173 192
 ATOMIC_FUNC_TEST(dec_and_test, "decl %0", int, int)
174 193
 ATOMIC_FUNC_XCHG(get_and_set,  "xchgl %1, %0", int)
194
+ATOMIC_FUNC_CMPXCHG(cmpxchg, "cmpxchgl %2, %1", int , int)
175 195
 #ifdef __CPU_x86_64
176 196
 ATOMIC_FUNC_DECL1(inc, "incq %0", long)
177 197
 ATOMIC_FUNC_DECL1(dec, "decq %0", long)
... ...
@@ -180,6 +200,7 @@ ATOMIC_FUNC_DECL2(or,  "orq %1, %0", long)
180 200
 ATOMIC_FUNC_TEST(inc_and_test, "incq %0", long, int)
181 201
 ATOMIC_FUNC_TEST(dec_and_test, "decq %0", long, int)
182 202
 ATOMIC_FUNC_XCHG(get_and_set,  "xchgq %1, %0", long)
203
+ATOMIC_FUNC_CMPXCHG(cmpxchg, "cmpxchgq %2, %1", long , long)
183 204
 #else
184 205
 ATOMIC_FUNC_DECL1(inc, "incl %0", long)
185 206
 ATOMIC_FUNC_DECL1(dec, "decl %0", long)
... ...
@@ -188,6 +209,7 @@ ATOMIC_FUNC_DECL2(or,  "orl %1, %0", long)
188 209
 ATOMIC_FUNC_TEST(inc_and_test, "incl %0", long, int)
189 210
 ATOMIC_FUNC_TEST(dec_and_test, "decl %0", long, int)
190 211
 ATOMIC_FUNC_XCHG(get_and_set,  "xchgl %1, %0", long)
212
+ATOMIC_FUNC_CMPXCHG(cmpxchg, "cmpxchgl %2, %1", long , long)
191 213
 #endif
192 214
 
193 215
 #define atomic_inc(var) atomic_inc_int(&(var)->val)
... ...
@@ -197,6 +219,8 @@ ATOMIC_FUNC_XCHG(get_and_set,  "xchgl %1, %0", long)
197 219
 #define atomic_dec_and_test(var) atomic_dec_and_test_int(&(var)->val)
198 220
 #define atomic_inc_and_test(var) atomic_inc_and_test_int(&(var)->val)
199 221
 #define atomic_get_and_set(var, i) atomic_get_and_set_int(&(var)->val, i)
222
+#define atomic_cmpxchg(var, old, newv) \
223
+		atomic_cmpxchg_int(&(var)->val, old, newv)
200 224
 
201 225
 
202 226
 #ifdef NOSMP