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#include <windows.h>
22#undef MemoryFence
23#endif
24
25#if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210)
26#define GNU_ATOMICS
27#endif
28
29void sys::MemoryFence() {
30#if LLVM_HAS_ATOMICS == 0
31  return;
32#else
33#  if defined(GNU_ATOMICS)
34  __sync_synchronize();
35#  elif defined(_MSC_VER)
36  MemoryBarrier();
37#  else
38# error No memory fence implementation for your platform!
39#  endif
40#endif
41}
42
43sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
44                                  sys::cas_flag new_value,
45                                  sys::cas_flag old_value) {
46#if LLVM_HAS_ATOMICS == 0
47  sys::cas_flag result = *ptr;
48  if (result == old_value)
49    *ptr = new_value;
50  return result;
51#elif defined(GNU_ATOMICS)
52  return __sync_val_compare_and_swap(ptr, old_value, new_value);
53#elif defined(_MSC_VER)
54  return InterlockedCompareExchange(ptr, new_value, old_value);
55#else
56#  error No compare-and-swap implementation for your platform!
57#endif
58}
59