Atomic.cpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements atomic operations.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Support/Atomic.h"
  13. #include "llvm/Config/llvm-config.h"
  14. using namespace llvm;
  15. #if defined(_MSC_VER)
  16. #include <intrin.h>
  17. // We must include windows.h after intrin.h.
  18. #include <windows.h>
  19. #undef MemoryFence
  20. #endif
  21. #if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210)
  22. #define GNU_ATOMICS
  23. #endif
  24. void sys::MemoryFence() {
  25. #if LLVM_HAS_ATOMICS == 0
  26. return;
  27. #else
  28. # if defined(GNU_ATOMICS)
  29. __sync_synchronize();
  30. # elif defined(_MSC_VER)
  31. MemoryBarrier();
  32. # else
  33. # error No memory fence implementation for your platform!
  34. # endif
  35. #endif
  36. }
  37. sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
  38. sys::cas_flag new_value,
  39. sys::cas_flag old_value) {
  40. #if LLVM_HAS_ATOMICS == 0
  41. sys::cas_flag result = *ptr;
  42. if (result == old_value)
  43. *ptr = new_value;
  44. return result;
  45. #elif defined(GNU_ATOMICS)
  46. return __sync_val_compare_and_swap(ptr, old_value, new_value);
  47. #elif defined(_MSC_VER)
  48. return InterlockedCompareExchange(ptr, new_value, old_value);
  49. #else
  50. # error No compare-and-swap implementation for your platform!
  51. #endif
  52. }