/* -*-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
#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,
+// Usually the appropriate functions are inlined by gcc.
+// But if gcc is called with something equivalent to -march=i386,
// it will not assume that there is a lock instruction and instead
// calls this pair of functions. We will provide them here in this case.
// Note that this assembler code will not work on a i386 chip anymore.
-// But I hardly believe that we can assume to run at least on a i486 ...
+// But I firmly believe that we can assume to run at least on a i486 ...
extern "C" {
: "=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)
: "=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()