Use instruction itinerary to determine what instructions are 'cheap'.
[oota-llvm.git] / include / llvm / System / Atomic.h
index 2f95e0f7fbbd8e31075f1bc64663e53d17fe5cc8..fc19369d11bdeb387f34ef02c741cea160736fad 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
-
+#include "llvm/System/DataTypes.h"
 
 namespace llvm {
   namespace sys {
-    
-#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);
-    }
+    void MemoryFence();
+
+#ifdef _MSC_VER
+    typedef long cas_flag;
 #else
-#error No memory atomics implementation for your platform!
+    typedef uint32_t cas_flag;
 #endif
-    
+    cas_flag CompareAndSwap(volatile cas_flag* ptr,
+                            cas_flag new_value,
+                            cas_flag old_value);
+    cas_flag AtomicIncrement(volatile cas_flag* ptr);
+    cas_flag AtomicDecrement(volatile cas_flag* ptr);
+    cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
+    cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
+    cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
   }
 }
 
-#endif
\ No newline at end of file
+#endif