60 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
//  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>
 | 
						|
 | 
						|
// We must include windows.h after 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
 | 
						|
}
 |