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 17using 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 31void 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 45sys::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