1 //===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements atomic operations. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Support/Atomic.h" 15 #include "llvm/Config/llvm-config.h" 16 17 using namespace llvm; 18 19 #if defined(_MSC_VER) 20 #include <intrin.h> 21 22 // We must include windows.h after intrin.h. 23 #include <windows.h> 24 #undef MemoryFence 25 #endif 26 27 #if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210) 28 #define GNU_ATOMICS 29 #endif 30 31 void sys::MemoryFence() { 32 #if LLVM_HAS_ATOMICS == 0 33 return; 34 #else 35 # if defined(GNU_ATOMICS) 36 __sync_synchronize(); 37 # elif defined(_MSC_VER) 38 MemoryBarrier(); 39 # else 40 # error No memory fence implementation for your platform! 41 # endif 42 #endif 43 } 44 45 sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr, 46 sys::cas_flag new_value, 47 sys::cas_flag old_value) { 48 #if LLVM_HAS_ATOMICS == 0 49 sys::cas_flag result = *ptr; 50 if (result == old_value) 51 *ptr = new_value; 52 return result; 53 #elif defined(GNU_ATOMICS) 54 return __sync_val_compare_and_swap(ptr, old_value, new_value); 55 #elif defined(_MSC_VER) 56 return InterlockedCompareExchange(ptr, new_value, old_value); 57 #else 58 # error No compare-and-swap implementation for your platform! 59 #endif 60 } 61