diff options
Diffstat (limited to 'llvm/lib/Support/Atomic.cpp')
-rw-r--r-- | llvm/lib/Support/Atomic.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/llvm/lib/Support/Atomic.cpp b/llvm/lib/Support/Atomic.cpp new file mode 100644 index 000000000000..f6865405c2b8 --- /dev/null +++ b/llvm/lib/Support/Atomic.cpp @@ -0,0 +1,59 @@ +//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements atomic operations. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Atomic.h" +#include "llvm/Config/llvm-config.h" + +using namespace llvm; + +#if defined(_MSC_VER) +#include <intrin.h> + +// We must include windows.h after intrin.h. +#include <windows.h> +#undef MemoryFence +#endif + +#if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210) +#define GNU_ATOMICS +#endif + +void sys::MemoryFence() { +#if LLVM_HAS_ATOMICS == 0 + return; +#else +# if defined(GNU_ATOMICS) + __sync_synchronize(); +# elif defined(_MSC_VER) + MemoryBarrier(); +# else +# error No memory fence implementation for your platform! +# endif +#endif +} + +sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr, + sys::cas_flag new_value, + sys::cas_flag old_value) { +#if LLVM_HAS_ATOMICS == 0 + sys::cas_flag result = *ptr; + if (result == old_value) + *ptr = new_value; + return result; +#elif defined(GNU_ATOMICS) + return __sync_val_compare_and_swap(ptr, old_value, new_value); +#elif defined(_MSC_VER) + return InterlockedCompareExchange(ptr, new_value, old_value); +#else +# error No compare-and-swap implementation for your platform! +#endif +} |