Label the existing atomic functions as 32-bit specific, and add a 64-bit one that...
[oota-llvm.git] / lib / System / Atomic.cpp
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 header file implements atomic operations.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/System/Atomic.h"
15 #include "llvm/Config/config.h"
16
17 using namespace llvm;
18
19 #if defined(_MSC_VER)
20 #include <windows.h>
21 #undef MemoryFence
22 #endif
23
24 void sys::MemoryFence() {
25 #if LLVM_MULTITHREADED==0
26   return;
27 #else
28 #  if defined(__GNUC__)
29   __sync_synchronize();
30 #  elif defined(_MSC_VER)
31   MemoryBarrier();
32 #  else
33 # error No memory fence implementation for your platform!
34 #  endif
35 #endif
36 }
37
38 uint32_t sys::CompareAndSwap32(volatile uint32_t* ptr,
39                                uint32_t new_value,
40                                uint32_t old_value) {
41 #if LLVM_MULTITHREADED==0
42   uint32_t result = *ptr;
43   if (result == old_value)
44     *ptr = new_value;
45   return result;
46 #elif defined(__GNUC__)
47   return __sync_val_compare_and_swap(ptr, old_value, new_value);
48 #elif defined(_MSC_VER)
49   return InterlockedCompareExchange(ptr, new_value, old_value);
50 #else
51 #  error No compare-and-swap implementation for your platform!
52 #endif
53 }
54
55 uint32_t sys::AtomicIncrement32(volatile uint32_t* ptr) {
56 #if LLVM_MULTITHREADED==0
57   ++(*ptr);
58   return *ptr;
59 #elif defined(__GNUC__)
60   return __sync_add_and_fetch(ptr, 1);
61 #elif defined(_MSC_VER)
62   return InterlockedIncrement(ptr);
63 #else
64 #  error No atomic increment implementation for your platform!
65 #endif
66 }
67
68 uint32_t sys::AtomicDecrement32(volatile uint32_t* ptr) {
69 #if LLVM_MULTITHREADED==0
70   --(*ptr);
71   return *ptr;
72 #elif defined(__GNUC__)
73   return __sync_sub_and_fetch(ptr, 1);
74 #elif defined(_MSC_VER)
75   return InterlockedDecrement(ptr);
76 #else
77 #  error No atomic decrement implementation for your platform!
78 #endif
79 }
80
81 uint32_t sys::AtomicAdd32(volatile uint32_t* ptr, uint32_t val) {
82 #if LLVM_MULTITHREADED==0
83   *ptr += val;
84   return *ptr;
85 #elif defined(__GNUC__)
86   return __sync_add_and_fetch(ptr, val);
87 #elif defined(_MSC_VER)
88   return InterlockedAdd(ptr, val);
89 #else
90 #  error No atomic add implementation for your platform!
91 #endif
92 }
93
94 uint64_t sys::AtomicAdd64(volatile uint64_t* ptr, uint64_t val) {
95 #if LLVM_MULTITHREADED==0
96   *ptr += val;
97   return *ptr;
98 #elif defined(__GNUC__)
99   return __sync_add_and_fetch(ptr, val);
100 #elif defined(_MSC_VER)
101   return InterlockedAdd64(ptr, val);
102 #else
103 #  error No atomic add implementation for your platform!
104 #endif
105 }
106