atomicops_internals_std.h 7.06 KB
Newer Older
1 2 3 4
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef V8_BASE_ATOMICOPS_INTERNALS_STD_H_
#define V8_BASE_ATOMICOPS_INTERNALS_STD_H_
7 8 9 10

#include <atomic>

#include "src/base/build_config.h"
11
#include "src/base/macros.h"
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

namespace v8 {
namespace base {

namespace helper {
template <typename T>
volatile std::atomic<T>* to_std_atomic(volatile T* ptr) {
  return reinterpret_cast<volatile std::atomic<T>*>(ptr);
}
template <typename T>
volatile const std::atomic<T>* to_std_atomic_const(volatile const T* ptr) {
  return reinterpret_cast<volatile const std::atomic<T>*>(ptr);
}
}  // namespace helper

inline void SeqCst_MemoryFence() {
  std::atomic_thread_fence(std::memory_order_seq_cst);
}

inline Atomic32 Relaxed_CompareAndSwap(volatile Atomic32* ptr,
                                       Atomic32 old_value, Atomic32 new_value) {
  std::atomic_compare_exchange_strong_explicit(
      helper::to_std_atomic(ptr), &old_value, new_value,
      std::memory_order_relaxed, std::memory_order_relaxed);
  return old_value;
}

inline Atomic32 Relaxed_AtomicExchange(volatile Atomic32* ptr,
                                       Atomic32 new_value) {
  return std::atomic_exchange_explicit(helper::to_std_atomic(ptr), new_value,
                                       std::memory_order_relaxed);
}

inline Atomic32 Relaxed_AtomicIncrement(volatile Atomic32* ptr,
                                        Atomic32 increment) {
  return increment + std::atomic_fetch_add_explicit(helper::to_std_atomic(ptr),
                                                    increment,
                                                    std::memory_order_relaxed);
}

inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
                                        Atomic32 increment) {
  return increment + std::atomic_fetch_add_explicit(helper::to_std_atomic(ptr),
                                                    increment,
                                                    std::memory_order_seq_cst);
}

inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
                                       Atomic32 old_value, Atomic32 new_value) {
  atomic_compare_exchange_strong_explicit(
      helper::to_std_atomic(ptr), &old_value, new_value,
      std::memory_order_acquire, std::memory_order_acquire);
  return old_value;
}

67 68 69 70 71 72 73 74 75
inline Atomic8 Release_CompareAndSwap(volatile Atomic8* ptr, Atomic8 old_value,
                                      Atomic8 new_value) {
  bool result = atomic_compare_exchange_strong_explicit(
      helper::to_std_atomic(ptr), &old_value, new_value,
      std::memory_order_release, std::memory_order_relaxed);
  USE(result);  // Make gcc compiler happy.
  return old_value;
}

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
                                       Atomic32 old_value, Atomic32 new_value) {
  atomic_compare_exchange_strong_explicit(
      helper::to_std_atomic(ptr), &old_value, new_value,
      std::memory_order_release, std::memory_order_relaxed);
  return old_value;
}

inline void Relaxed_Store(volatile Atomic8* ptr, Atomic8 value) {
  std::atomic_store_explicit(helper::to_std_atomic(ptr), value,
                             std::memory_order_relaxed);
}

inline void Relaxed_Store(volatile Atomic32* ptr, Atomic32 value) {
  std::atomic_store_explicit(helper::to_std_atomic(ptr), value,
                             std::memory_order_relaxed);
}

inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
  std::atomic_store_explicit(helper::to_std_atomic(ptr), value,
                             std::memory_order_release);
}

inline Atomic8 Relaxed_Load(volatile const Atomic8* ptr) {
  return std::atomic_load_explicit(helper::to_std_atomic_const(ptr),
                                   std::memory_order_relaxed);
}

inline Atomic32 Relaxed_Load(volatile const Atomic32* ptr) {
  return std::atomic_load_explicit(helper::to_std_atomic_const(ptr),
                                   std::memory_order_relaxed);
}

inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
  return std::atomic_load_explicit(helper::to_std_atomic_const(ptr),
                                   std::memory_order_acquire);
}

#if defined(V8_HOST_ARCH_64_BIT)

inline Atomic64 Relaxed_CompareAndSwap(volatile Atomic64* ptr,
                                       Atomic64 old_value, Atomic64 new_value) {
  std::atomic_compare_exchange_strong_explicit(
      helper::to_std_atomic(ptr), &old_value, new_value,
      std::memory_order_relaxed, std::memory_order_relaxed);
  return old_value;
}

inline Atomic64 Relaxed_AtomicExchange(volatile Atomic64* ptr,
                                       Atomic64 new_value) {
  return std::atomic_exchange_explicit(helper::to_std_atomic(ptr), new_value,
                                       std::memory_order_relaxed);
}

inline Atomic64 Relaxed_AtomicIncrement(volatile Atomic64* ptr,
                                        Atomic64 increment) {
  return increment + std::atomic_fetch_add_explicit(helper::to_std_atomic(ptr),
                                                    increment,
                                                    std::memory_order_relaxed);
}

inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
                                        Atomic64 increment) {
  return increment + std::atomic_fetch_add_explicit(helper::to_std_atomic(ptr),
                                                    increment,
                                                    std::memory_order_seq_cst);
}

inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
                                       Atomic64 old_value, Atomic64 new_value) {
  std::atomic_compare_exchange_strong_explicit(
      helper::to_std_atomic(ptr), &old_value, new_value,
      std::memory_order_acquire, std::memory_order_acquire);
  return old_value;
}

inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
                                       Atomic64 old_value, Atomic64 new_value) {
  std::atomic_compare_exchange_strong_explicit(
      helper::to_std_atomic(ptr), &old_value, new_value,
      std::memory_order_release, std::memory_order_relaxed);
  return old_value;
}

inline void Relaxed_Store(volatile Atomic64* ptr, Atomic64 value) {
  std::atomic_store_explicit(helper::to_std_atomic(ptr), value,
                             std::memory_order_relaxed);
}

inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
  std::atomic_store_explicit(helper::to_std_atomic(ptr), value,
                             std::memory_order_release);
}

inline Atomic64 Relaxed_Load(volatile const Atomic64* ptr) {
  return std::atomic_load_explicit(helper::to_std_atomic_const(ptr),
                                   std::memory_order_relaxed);
}

inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
  return std::atomic_load_explicit(helper::to_std_atomic_const(ptr),
                                   std::memory_order_acquire);
}

#endif  // defined(V8_HOST_ARCH_64_BIT)
}  // namespace base
}  // namespace v8

#endif  // V8_BASE_ATOMICOPS_INTERNALS_STD_H_