1 //===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This header file implements atomic operations.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/System/Atomic.h"
15 #include "llvm/Config/config.h"
24 void sys::MemoryFence() {
25 #if LLVM_MULTITHREADED==0
28 # if defined(__GNUC__)
30 # elif defined(_MSC_VER)
33 # error No memory fence implementation for your platform!
38 sys::cas_flag
sys::CompareAndSwap(volatile sys::cas_flag
* ptr
,
39 sys::cas_flag new_value
,
40 sys::cas_flag old_value
) {
41 #if LLVM_MULTITHREADED==0
42 sys::cas_flag result
= *ptr
;
43 if (result
== old_value
)
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
);
51 # error No compare-and-swap implementation for your platform!
55 sys::cas_flag
sys::AtomicIncrement(volatile sys::cas_flag
* ptr
) {
56 #if LLVM_MULTITHREADED==0
59 #elif defined(__GNUC__)
60 return __sync_add_and_fetch(ptr
, 1);
61 #elif defined(_MSC_VER)
62 return InterlockedIncrement(ptr
);
64 # error No atomic increment implementation for your platform!
68 sys::cas_flag
sys::AtomicDecrement(volatile sys::cas_flag
* ptr
) {
69 #if LLVM_MULTITHREADED==0
72 #elif defined(__GNUC__)
73 return __sync_sub_and_fetch(ptr
, 1);
74 #elif defined(_MSC_VER)
75 return InterlockedDecrement(ptr
);
77 # error No atomic decrement implementation for your platform!
81 sys::cas_flag
sys::AtomicAdd(volatile sys::cas_flag
* ptr
, sys::cas_flag val
) {
82 #if LLVM_MULTITHREADED==0
85 #elif defined(__GNUC__)
86 return __sync_add_and_fetch(ptr
, val
);
87 #elif defined(_MSC_VER)
88 return InterlockedExchangeAdd(ptr
, val
) + val
;
90 # error No atomic add implementation for your platform!
94 sys::cas_flag
sys::AtomicMul(volatile sys::cas_flag
* ptr
, sys::cas_flag val
) {
95 sys::cas_flag original
, result
;
98 result
= original
* val
;
99 } while (sys::CompareAndSwap(ptr
, result
, original
) != original
);
104 sys::cas_flag
sys::AtomicDiv(volatile sys::cas_flag
* ptr
, sys::cas_flag val
) {
105 sys::cas_flag original
, result
;
108 result
= original
/ val
;
109 } while (sys::CompareAndSwap(ptr
, result
, original
) != original
);