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 16using 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 30void 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 44sys::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