blob: 80550e2b46a7c735cfdcdbf10f676b3a961b3825 [file] [log] [blame]
Owen Andersone5370f42009-05-20 18:26:15 +00001//===-- 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//
Hans Wennborgcfe341f2014-06-20 01:36:00 +000010// This file implements atomic operations.
Owen Andersone5370f42009-05-20 18:26:15 +000011//
12//===----------------------------------------------------------------------===//
13
Michael J. Spencer447762d2010-11-29 18:16:10 +000014#include "llvm/Support/Atomic.h"
Dylan Noblesmith9e5b1782011-12-22 23:04:07 +000015#include "llvm/Config/llvm-config.h"
Owen Andersone5370f42009-05-20 18:26:15 +000016
17using namespace llvm;
18
19#if defined(_MSC_VER)
Reid Kleckner64c75a52014-05-06 00:57:33 +000020#include <Intrin.h>
Owen Andersone5370f42009-05-20 18:26:15 +000021#include <windows.h>
Owen Anderson5bd914d2009-06-02 17:35:55 +000022#undef MemoryFence
Owen Andersone5370f42009-05-20 18:26:15 +000023#endif
24
Rafael Espindola2f92f612012-11-02 20:54:45 +000025#if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210)
26#define GNU_ATOMICS
27#endif
28
Owen Andersone5370f42009-05-20 18:26:15 +000029void sys::MemoryFence() {
Eric Christopher4418a602011-09-19 20:43:23 +000030#if LLVM_HAS_ATOMICS == 0
Owen Andersone5370f42009-05-20 18:26:15 +000031 return;
32#else
Rafael Espindola2f92f612012-11-02 20:54:45 +000033# if defined(GNU_ATOMICS)
Owen Andersone5370f42009-05-20 18:26:15 +000034 __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
Owen Anderson5cc41312009-06-23 20:17:22 +000043sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
44 sys::cas_flag new_value,
45 sys::cas_flag old_value) {
Eric Christopher4418a602011-09-19 20:43:23 +000046#if LLVM_HAS_ATOMICS == 0
Owen Anderson5cc41312009-06-23 20:17:22 +000047 sys::cas_flag result = *ptr;
Owen Anderson5b9400d2009-05-20 19:01:50 +000048 if (result == old_value)
49 *ptr = new_value;
Owen Andersone5370f42009-05-20 18:26:15 +000050 return result;
Rafael Espindola2f92f612012-11-02 20:54:45 +000051#elif defined(GNU_ATOMICS)
Owen Andersone5370f42009-05-20 18:26:15 +000052 return __sync_val_compare_and_swap(ptr, old_value, new_value);
53#elif defined(_MSC_VER)
Owen Anderson76ae5dd2009-05-20 19:06:49 +000054 return InterlockedCompareExchange(ptr, new_value, old_value);
Owen Andersone5370f42009-05-20 18:26:15 +000055#else
56# error No compare-and-swap implementation for your platform!
57#endif
Duncan Sands06b61a22009-06-03 11:54:28 +000058}