Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Support/Atomic.cpp @ 0:95c75e76d11b
LLVM 3.4
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 12 Dec 2013 13:56:28 +0900 |
parents | |
children | 54457678186b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:95c75e76d11b |
---|---|
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/Support/Atomic.h" | |
15 #include "llvm/Config/llvm-config.h" | |
16 | |
17 using namespace llvm; | |
18 | |
19 #if defined(_MSC_VER) | |
20 #include <windows.h> | |
21 #undef MemoryFence | |
22 #endif | |
23 | |
24 #if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210) | |
25 #define GNU_ATOMICS | |
26 #endif | |
27 | |
28 void sys::MemoryFence() { | |
29 #if LLVM_HAS_ATOMICS == 0 | |
30 return; | |
31 #else | |
32 # if defined(GNU_ATOMICS) | |
33 __sync_synchronize(); | |
34 # elif defined(_MSC_VER) | |
35 MemoryBarrier(); | |
36 # else | |
37 # error No memory fence implementation for your platform! | |
38 # endif | |
39 #endif | |
40 } | |
41 | |
42 sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr, | |
43 sys::cas_flag new_value, | |
44 sys::cas_flag old_value) { | |
45 #if LLVM_HAS_ATOMICS == 0 | |
46 sys::cas_flag result = *ptr; | |
47 if (result == old_value) | |
48 *ptr = new_value; | |
49 return result; | |
50 #elif defined(GNU_ATOMICS) | |
51 return __sync_val_compare_and_swap(ptr, old_value, new_value); | |
52 #elif defined(_MSC_VER) | |
53 return InterlockedCompareExchange(ptr, new_value, old_value); | |
54 #else | |
55 # error No compare-and-swap implementation for your platform! | |
56 #endif | |
57 } | |
58 | |
59 sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) { | |
60 #if LLVM_HAS_ATOMICS == 0 | |
61 ++(*ptr); | |
62 return *ptr; | |
63 #elif defined(GNU_ATOMICS) | |
64 return __sync_add_and_fetch(ptr, 1); | |
65 #elif defined(_MSC_VER) | |
66 return InterlockedIncrement(ptr); | |
67 #else | |
68 # error No atomic increment implementation for your platform! | |
69 #endif | |
70 } | |
71 | |
72 sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) { | |
73 #if LLVM_HAS_ATOMICS == 0 | |
74 --(*ptr); | |
75 return *ptr; | |
76 #elif defined(GNU_ATOMICS) | |
77 return __sync_sub_and_fetch(ptr, 1); | |
78 #elif defined(_MSC_VER) | |
79 return InterlockedDecrement(ptr); | |
80 #else | |
81 # error No atomic decrement implementation for your platform! | |
82 #endif | |
83 } | |
84 | |
85 sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) { | |
86 #if LLVM_HAS_ATOMICS == 0 | |
87 *ptr += val; | |
88 return *ptr; | |
89 #elif defined(GNU_ATOMICS) | |
90 return __sync_add_and_fetch(ptr, val); | |
91 #elif defined(_MSC_VER) | |
92 return InterlockedExchangeAdd(ptr, val) + val; | |
93 #else | |
94 # error No atomic add implementation for your platform! | |
95 #endif | |
96 } | |
97 | |
98 sys::cas_flag sys::AtomicMul(volatile sys::cas_flag* ptr, sys::cas_flag val) { | |
99 sys::cas_flag original, result; | |
100 do { | |
101 original = *ptr; | |
102 result = original * val; | |
103 } while (sys::CompareAndSwap(ptr, result, original) != original); | |
104 | |
105 return result; | |
106 } | |
107 | |
108 sys::cas_flag sys::AtomicDiv(volatile sys::cas_flag* ptr, sys::cas_flag val) { | |
109 sys::cas_flag original, result; | |
110 do { | |
111 original = *ptr; | |
112 result = original / val; | |
113 } while (sys::CompareAndSwap(ptr, result, original) != original); | |
114 | |
115 return result; | |
116 } |