We need to include config.h here so that the #defines are set properly.
[oota-llvm.git] / include / llvm / System / Atomic.h
1 //===- llvm/System/Atomic.h - 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 declares the llvm::sys atomic operations.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_SYSTEM_ATOMIC_H
15 #define LLVM_SYSTEM_ATOMIC_H
16
17 #include "llvm/Config/config.h"
18
19 #if defined(_MSC_VER)
20 #include <windows.h>
21 #endif
22
23
24 namespace llvm {
25   namespace sys {
26     
27     inline void MemoryFence() {
28 #if LLVM_MULTITHREADED==0
29       return;
30 #else
31 #  if defined(__GNUC__)
32       __sync_synchronize();
33 #  elif defined(_MSC_VER)
34       MemoryBarrier();
35 #  else
36 #    error No memory fence implementation for your platform!
37 #  endif
38 #endif
39 }
40
41 #if LLVM_MULTITHREADED==0
42     typedef unsigned long cas_flag;
43     template<typename T>
44     inline T CompareAndSwap(volatile T* dest,
45                             T exc, T c) {
46       T result = *dest;
47       if (result == c)
48         *dest = exc;
49       return result;
50     }
51 #elif defined(__GNUC__)
52     typedef unsigned long cas_flag;
53     template<typename T>
54     inline T CompareAndSwap(volatile T* ptr,
55                             T new_value,
56                             T old_value) {
57       return __sync_val_compare_and_swap(ptr, old_value, new_value);
58     }
59 #elif defined(_MSC_VER)
60     typedef LONG cas_flag;
61     template<typename T>
62     inline T CompareAndSwap(volatile T* ptr,
63                             T new_value,
64                             T old_value) {
65       if (sizeof(T) == 4)
66         return InterlockedCompareExchange(ptr, new_value, old_value);
67       else if (sizeof(T) == 8)
68         return InterlockedCompareExchange64(ptr, new_value, old_value);
69       else
70         assert(0 && "Unsupported compare-and-swap size!");
71     }
72     
73     template<typename T>
74     inline T* CompareAndSwap<T*>(volatile T** ptr,
75                                  T* new_value,
76                                  T* old_value) {
77       return InterlockedCompareExchangePtr(ptr, new_value, old_value);
78     }
79
80
81 #else
82 #  error No compare-and-swap implementation for your platform!
83 #endif
84
85   }
86 }
87
88 #endif