]> git.mxchange.org Git - simgear.git/blobdiff - simgear/structure/SGAtomic.cxx
SGExpression bugfix: allow <sin> within <product>
[simgear.git] / simgear / structure / SGAtomic.cxx
index 3505fabf601b2c9ca57eccf0f8e6f48ea3285b51..e7dd76c29a3883c38aaf975e75487f8166bd49cc 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c++-*-
  *
- * Copyright (C) 2005-2006 Mathias Froehlich 
+ * Copyright (C) 2005-2009 Mathias Froehlich 
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -20,7 +20,7 @@
 
 #include "SGAtomic.hxx"
 
-#if defined(SGATOMIC_USE_GCC4_BUILTINS) && defined(__i386__)
+#if defined(SGATOMIC_USE_GCC4_BUILTINS) && defined (__i386__)
 
 // Usually the apropriate functions are inlined by gcc.
 // But if gcc is called with something aequivalent to -march=i386,
@@ -39,7 +39,7 @@ unsigned __sync_sub_and_fetch_4(volatile void *ptr, unsigned value)
                        : "=r" (result), "=m" (*mem)
                        : "0" (-value), "m" (*mem)
                        : "memory");
-  return result;
+  return result - value;
 }
 
 unsigned __sync_add_and_fetch_4(volatile void *ptr, unsigned value)
@@ -50,7 +50,19 @@ unsigned __sync_add_and_fetch_4(volatile void *ptr, unsigned value)
                        : "=r" (result), "=m" (*mem)
                        : "0" (value), "m" (*mem)
                        : "memory");
-  return result;
+  return result + value;
+}
+
+unsigned __sync_bool_compare_and_swap_4(volatile void *ptr,
+                                        unsigned oldValue, unsigned newValue)
+{
+  register volatile unsigned* mem = reinterpret_cast<volatile unsigned*>(ptr);
+  unsigned before;
+  __asm__ __volatile__("lock; cmpxchg{l} {%1,%2|%1,%2}"
+                       : "=a"(before)
+                       : "q"(newValue), "m"(*mem), "0"(oldValue)
+                       : "memory");
+  return before == oldValue;
 }
 
 void __sync_synchronize()