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 165
 		return ret; \
166 166
 	}
167 167
 
168
+/* returns a value, 3 params (var, old, new)
169
+ * The returned value is the value before the xchg:
170
+ *  if ret!=old => cmpxchg failed and ret is var's value
171
+ *  else  => success and new_v is var's new value */
172
+#define ATOMIC_FUNC_CMPXCHG(NAME, OP, P_TYPE, RET_TYPE) \
173
+	inline static RET_TYPE atomic_##NAME##_##P_TYPE(volatile P_TYPE* var, \
174
+													P_TYPE old, P_TYPE new_v)\
175
+	{ \
176
+		P_TYPE ret; \
177
+		asm volatile( \
178
+				__LOCK_PREF " " OP "\n\t" \
179
+				: "=a"(ret), "=m" (*var) :\
180
+					"r"(new_v), "m"(*var), "0"(old):\
181
+					"cc", "memory" \
182
+				); \
183
+		return ret; \
184
+	}
185
+
168 186
 ATOMIC_FUNC_DECL1(inc, "incl %0", int)
169 187
 ATOMIC_FUNC_DECL1(dec, "decl %0", int)
170 188
 ATOMIC_FUNC_DECL2(and, "andl %1, %0", int)
... ...
@@ -172,6 +191,7 @@ ATOMIC_FUNC_DECL2(or,  "orl %1, %0", int)
172 172
 ATOMIC_FUNC_TEST(inc_and_test, "incl %0", int, int)
173 173
 ATOMIC_FUNC_TEST(dec_and_test, "decl %0", int, int)
174 174
 ATOMIC_FUNC_XCHG(get_and_set,  "xchgl %1, %0", int)
175
+ATOMIC_FUNC_CMPXCHG(cmpxchg, "cmpxchgl %2, %1", int , int)
175 176
 #ifdef __CPU_x86_64
176 177
 ATOMIC_FUNC_DECL1(inc, "incq %0", long)
177 178
 ATOMIC_FUNC_DECL1(dec, "decq %0", long)
... ...
@@ -180,6 +200,7 @@ ATOMIC_FUNC_DECL2(or,  "orq %1, %0", long)
180 180
 ATOMIC_FUNC_TEST(inc_and_test, "incq %0", long, int)
181 181
 ATOMIC_FUNC_TEST(dec_and_test, "decq %0", long, int)
182 182
 ATOMIC_FUNC_XCHG(get_and_set,  "xchgq %1, %0", long)
183
+ATOMIC_FUNC_CMPXCHG(cmpxchg, "cmpxchgq %2, %1", long , long)
183 184
 #else
184 185
 ATOMIC_FUNC_DECL1(inc, "incl %0", long)
185 186
 ATOMIC_FUNC_DECL1(dec, "decl %0", long)
... ...
@@ -188,6 +209,7 @@ ATOMIC_FUNC_DECL2(or,  "orl %1, %0", long)
188 188
 ATOMIC_FUNC_TEST(inc_and_test, "incl %0", long, int)
189 189
 ATOMIC_FUNC_TEST(dec_and_test, "decl %0", long, int)
190 190
 ATOMIC_FUNC_XCHG(get_and_set,  "xchgl %1, %0", long)
191
+ATOMIC_FUNC_CMPXCHG(cmpxchg, "cmpxchgl %2, %1", long , long)
191 192
 #endif
192 193
 
193 194
 #define atomic_inc(var) atomic_inc_int(&(var)->val)
... ...
@@ -197,6 +219,8 @@ ATOMIC_FUNC_XCHG(get_and_set,  "xchgl %1, %0", long)
197 197
 #define atomic_dec_and_test(var) atomic_dec_and_test_int(&(var)->val)
198 198
 #define atomic_inc_and_test(var) atomic_inc_and_test_int(&(var)->val)
199 199
 #define atomic_get_and_set(var, i) atomic_get_and_set_int(&(var)->val, i)
200
+#define atomic_cmpxchg(var, old, newv) \
201
+		atomic_cmpxchg_int(&(var)->val, old, newv)
200 202
 
201 203
 
202 204
 #ifdef NOSMP