Move atomic operations' definitions out of line. While this seems kind of silly,

all kinds of problems caused by including windows.h and/or config.h in an LLVM header.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72174 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson 2009-05-20 18:26:15 +00:00
parent 261f2a2337
commit 3c1eaa0dc2
2 changed files with 58 additions and 65 deletions

View File

@ -14,75 +14,16 @@
#ifndef LLVM_SYSTEM_ATOMIC_H
#define LLVM_SYSTEM_ATOMIC_H
#include "llvm/Config/config.h"
#if defined(_MSC_VER)
#define NOMINMAX
#include <windows.h>
#endif
#include <stdint.h>
namespace llvm {
namespace sys {
inline void MemoryFence() {
#if LLVM_MULTITHREADED==0
return;
#else
# if defined(__GNUC__)
__sync_synchronize();
# elif defined(_MSC_VER)
MemoryBarrier();
# else
# error No memory fence implementation for your platform!
# endif
#endif
}
#if LLVM_MULTITHREADED==0
typedef unsigned long cas_flag;
template<typename T>
inline T CompareAndSwap(volatile T* dest,
T exc, T c) {
T result = *dest;
if (result == c)
*dest = exc;
return result;
}
#elif defined(__GNUC__)
typedef unsigned long cas_flag;
template<typename T>
inline T CompareAndSwap(volatile T* ptr,
T new_value,
T old_value) {
return __sync_val_compare_and_swap(ptr, old_value, new_value);
}
#elif defined(_MSC_VER)
typedef LONG cas_flag;
template<typename T>
inline T CompareAndSwap(volatile T* ptr,
T new_value,
T old_value) {
if (sizeof(T) == 4)
return InterlockedCompareExchange(ptr, new_value, old_value);
else if (sizeof(T) == 8)
return InterlockedCompareExchange64(ptr, new_value, old_value);
else
assert(0 && "Unsupported compare-and-swap size!");
}
template<typename T>
inline T* CompareAndSwap<T*>(volatile T** ptr,
T* new_value,
T* old_value) {
return InterlockedCompareExchangePtr(ptr, new_value, old_value);
}
#else
# error No compare-and-swap implementation for your platform!
#endif
void MemoryFence();
typedef uint32_t cas_flag;
cas_flag CompareAndSwap(volatile cas_flag* ptr,
cas_flag new_value,
cas_flag old_value);
}
}

52
lib/System/Atomic.cpp Normal file
View File

@ -0,0 +1,52 @@
//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header file implements atomic operations.
//
//===----------------------------------------------------------------------===//
#include "llvm/System/Atomic.h"
#include "llvm/Config/config.h"
using namespace llvm;
#if defined(_MSC_VER)
#include <windows.h>
#endif
void sys::MemoryFence() {
#if LLVM_MULTITHREADED==0
return;
#else
# if defined(__GNUC__)
__sync_synchronize();
# elif defined(_MSC_VER)
MemoryBarrier();
# else
# error No memory fence implementation for your platform!
# endif
#endif
}
sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
sys::cas_flag new_value,
sys::cas_flag old_value) {
#if LLVM_MULTITHREADED==0
T result = *dest;
if (result == c)
*dest = exc;
return result;
#elif defined(__GNUC__)
return __sync_val_compare_and_swap(ptr, old_value, new_value);
#elif defined(_MSC_VER)
return InterlockedCompareExchange(ptr, new_value, old_value);
#else
# error No compare-and-swap implementation for your platform!
#endif
}