59 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- 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 file implements atomic operations.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "llvm/Support/Atomic.h"
 | 
						|
#include "llvm/Config/llvm-config.h"
 | 
						|
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
#if defined(_MSC_VER)
 | 
						|
#include <Intrin.h>
 | 
						|
#include <windows.h>
 | 
						|
#undef MemoryFence
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210)
 | 
						|
#define GNU_ATOMICS
 | 
						|
#endif
 | 
						|
 | 
						|
void sys::MemoryFence() {
 | 
						|
#if LLVM_HAS_ATOMICS == 0
 | 
						|
  return;
 | 
						|
#else
 | 
						|
#  if defined(GNU_ATOMICS)
 | 
						|
  __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_HAS_ATOMICS == 0
 | 
						|
  sys::cas_flag result = *ptr;
 | 
						|
  if (result == old_value)
 | 
						|
    *ptr = new_value;
 | 
						|
  return result;
 | 
						|
#elif defined(GNU_ATOMICS)
 | 
						|
  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
 | 
						|
}
 |