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