Add CompareAndSwap.
authorOwen Anderson <resistor@mac.com>
Thu, 14 May 2009 21:24:15 +0000 (21:24 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 14 May 2009 21:24:15 +0000 (21:24 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71795 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/System/Atomic.h

index 7db31d52dce0d56c2159aaa4aed45d163966b544..3f788074d9b94763724d67d8f02f71eba52a200b 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#ifndef LLVM_SYSTEM_ATOMIC_H
+#define LLVM_SYSTEM_ATOMIC_H
+
 #include "llvm/Config/config.h"
+#include <stdint.h>
 
 #ifdef __APPLE__
-#include <libkern/OSAtomic.h>
+
 #elif LLVM_ON_WIN32
 #include <windows.h>
 #endif
 
 
-#ifndef LLVM_SYSTEM_ATOMIC_H
-#define LLVM_SYSTEM_ATOMIC_H
-
 namespace llvm {
   namespace sys {
-    inline void MemoryFence() {
+    
 #if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
+    inline void MemoryFence() {
       return;
+    }
+    
+    typedef uint32_t cas_flag;
+    inline cas_flag CompareAndSwap(cas_flag* dest, cas_flag exc, cas_flag c) {
+      cas_flag result = *dest;
+      if (result == c)
+        *dest = exc;
+      return result;
+    }
+    
 #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+    inline void MemoryFence() {
       __sync_synchronize();
+    }
+    
+    typedef volatile uint32_t cas_flag;
+    inline cas_flag CompareAndSwap(cas_flag* dest, cas_flag exc, cas_flag c) {
+      return __sync_val_compare_and_swap(dest, exc, c);
+    }
+    
 #elif defined(__APPLE__)
+    inline void MemoryFence() {
       OSMemoryBarrier();
+    }
+    
+    typedef volatile UInt32 cas_flag;
+    inline cas_flag CompareAndSwap(cas_flag* dest, cas_flag exc, cas_flag c) {
+      cas_flag old = *dest;
+      OSCompareAndSwap(c, exc, dest);
+      return old;
+    }
 #elif defined(LLVM_ON_WIN32)
 #warning Memory fence implementation requires Windows 2003 or later.
+    inline void MemoryFence() {
       MemoryBarrier();
+    }
+    
+    typedef volatile long cas_flag;
+    inline cas_flag CompareAndSwap(cas_flag* dest, cas_flag exc, cas_flag c) {
+      return _InterlockedCompareExchange(dest, exc, c);
+    }
 #else
-#warning No memory fence implementation found for you platform!
+#error No memory atomics implementation for your platform!
 #endif
-    }
+    
   }
 }