1// Copyright 2012 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5 6// This file is an internal atomic implementation for compiler-based 7// ThreadSanitizer. Use base/atomicops.h instead. 8 9#ifndef V8_BASE_ATOMICOPS_INTERNALS_TSAN_H_ 10#define V8_BASE_ATOMICOPS_INTERNALS_TSAN_H_ 11 12namespace v8 { 13namespace base { 14 15#ifndef TSAN_INTERFACE_ATOMIC_H 16#define TSAN_INTERFACE_ATOMIC_H 17 18 19extern "C" { 20typedef char __tsan_atomic8; 21typedef short __tsan_atomic16; // NOLINT 22typedef int __tsan_atomic32; 23typedef long __tsan_atomic64; // NOLINT 24 25#if defined(__SIZEOF_INT128__) \ 26 || (__clang_major__ * 100 + __clang_minor__ >= 302) 27typedef __int128 __tsan_atomic128; 28#define __TSAN_HAS_INT128 1 29#else 30typedef char __tsan_atomic128; 31#define __TSAN_HAS_INT128 0 32#endif 33 34typedef enum { 35 __tsan_memory_order_relaxed, 36 __tsan_memory_order_consume, 37 __tsan_memory_order_acquire, 38 __tsan_memory_order_release, 39 __tsan_memory_order_acq_rel, 40 __tsan_memory_order_seq_cst, 41} __tsan_memory_order; 42 43__tsan_atomic8 __tsan_atomic8_load(const volatile __tsan_atomic8* a, 44 __tsan_memory_order mo); 45__tsan_atomic16 __tsan_atomic16_load(const volatile __tsan_atomic16* a, 46 __tsan_memory_order mo); 47__tsan_atomic32 __tsan_atomic32_load(const volatile __tsan_atomic32* a, 48 __tsan_memory_order mo); 49__tsan_atomic64 __tsan_atomic64_load(const volatile __tsan_atomic64* a, 50 __tsan_memory_order mo); 51__tsan_atomic128 __tsan_atomic128_load(const volatile __tsan_atomic128* a, 52 __tsan_memory_order mo); 53 54void __tsan_atomic8_store(volatile __tsan_atomic8* a, __tsan_atomic8 v, 55 __tsan_memory_order mo); 56void __tsan_atomic16_store(volatile __tsan_atomic16* a, __tsan_atomic16 v, 57 __tsan_memory_order mo); 58void __tsan_atomic32_store(volatile __tsan_atomic32* a, __tsan_atomic32 v, 59 __tsan_memory_order mo); 60void __tsan_atomic64_store(volatile __tsan_atomic64* a, __tsan_atomic64 v, 61 __tsan_memory_order mo); 62void __tsan_atomic128_store(volatile __tsan_atomic128* a, __tsan_atomic128 v, 63 __tsan_memory_order mo); 64 65__tsan_atomic8 __tsan_atomic8_exchange(volatile __tsan_atomic8* a, 66 __tsan_atomic8 v, __tsan_memory_order mo); 67__tsan_atomic16 __tsan_atomic16_exchange(volatile __tsan_atomic16* a, 68 __tsan_atomic16 v, __tsan_memory_order mo); 69__tsan_atomic32 __tsan_atomic32_exchange(volatile __tsan_atomic32* a, 70 __tsan_atomic32 v, __tsan_memory_order mo); 71__tsan_atomic64 __tsan_atomic64_exchange(volatile __tsan_atomic64* a, 72 __tsan_atomic64 v, __tsan_memory_order mo); 73__tsan_atomic128 __tsan_atomic128_exchange(volatile __tsan_atomic128* a, 74 __tsan_atomic128 v, __tsan_memory_order mo); 75 76__tsan_atomic8 __tsan_atomic8_fetch_add(volatile __tsan_atomic8* a, 77 __tsan_atomic8 v, __tsan_memory_order mo); 78__tsan_atomic16 __tsan_atomic16_fetch_add(volatile __tsan_atomic16* a, 79 __tsan_atomic16 v, __tsan_memory_order mo); 80__tsan_atomic32 __tsan_atomic32_fetch_add(volatile __tsan_atomic32* a, 81 __tsan_atomic32 v, __tsan_memory_order mo); 82__tsan_atomic64 __tsan_atomic64_fetch_add(volatile __tsan_atomic64* a, 83 __tsan_atomic64 v, __tsan_memory_order mo); 84__tsan_atomic128 __tsan_atomic128_fetch_add(volatile __tsan_atomic128* a, 85 __tsan_atomic128 v, __tsan_memory_order mo); 86 87__tsan_atomic8 __tsan_atomic8_fetch_and(volatile __tsan_atomic8* a, 88 __tsan_atomic8 v, __tsan_memory_order mo); 89__tsan_atomic16 __tsan_atomic16_fetch_and(volatile __tsan_atomic16* a, 90 __tsan_atomic16 v, __tsan_memory_order mo); 91__tsan_atomic32 __tsan_atomic32_fetch_and(volatile __tsan_atomic32* a, 92 __tsan_atomic32 v, __tsan_memory_order mo); 93__tsan_atomic64 __tsan_atomic64_fetch_and(volatile __tsan_atomic64* a, 94 __tsan_atomic64 v, __tsan_memory_order mo); 95__tsan_atomic128 __tsan_atomic128_fetch_and(volatile __tsan_atomic128* a, 96 __tsan_atomic128 v, __tsan_memory_order mo); 97 98__tsan_atomic8 __tsan_atomic8_fetch_or(volatile __tsan_atomic8* a, 99 __tsan_atomic8 v, __tsan_memory_order mo); 100__tsan_atomic16 __tsan_atomic16_fetch_or(volatile __tsan_atomic16* a, 101 __tsan_atomic16 v, __tsan_memory_order mo); 102__tsan_atomic32 __tsan_atomic32_fetch_or(volatile __tsan_atomic32* a, 103 __tsan_atomic32 v, __tsan_memory_order mo); 104__tsan_atomic64 __tsan_atomic64_fetch_or(volatile __tsan_atomic64* a, 105 __tsan_atomic64 v, __tsan_memory_order mo); 106__tsan_atomic128 __tsan_atomic128_fetch_or(volatile __tsan_atomic128* a, 107 __tsan_atomic128 v, __tsan_memory_order mo); 108 109__tsan_atomic8 __tsan_atomic8_fetch_xor(volatile __tsan_atomic8* a, 110 __tsan_atomic8 v, __tsan_memory_order mo); 111__tsan_atomic16 __tsan_atomic16_fetch_xor(volatile __tsan_atomic16* a, 112 __tsan_atomic16 v, __tsan_memory_order mo); 113__tsan_atomic32 __tsan_atomic32_fetch_xor(volatile __tsan_atomic32* a, 114 __tsan_atomic32 v, __tsan_memory_order mo); 115__tsan_atomic64 __tsan_atomic64_fetch_xor(volatile __tsan_atomic64* a, 116 __tsan_atomic64 v, __tsan_memory_order mo); 117__tsan_atomic128 __tsan_atomic128_fetch_xor(volatile __tsan_atomic128* a, 118 __tsan_atomic128 v, __tsan_memory_order mo); 119 120__tsan_atomic8 __tsan_atomic8_fetch_nand(volatile __tsan_atomic8* a, 121 __tsan_atomic8 v, __tsan_memory_order mo); 122__tsan_atomic16 __tsan_atomic16_fetch_nand(volatile __tsan_atomic16* a, 123 __tsan_atomic16 v, __tsan_memory_order mo); 124__tsan_atomic32 __tsan_atomic32_fetch_nand(volatile __tsan_atomic32* a, 125 __tsan_atomic32 v, __tsan_memory_order mo); 126__tsan_atomic64 __tsan_atomic64_fetch_nand(volatile __tsan_atomic64* a, 127 __tsan_atomic64 v, __tsan_memory_order mo); 128__tsan_atomic128 __tsan_atomic128_fetch_nand(volatile __tsan_atomic128* a, 129 __tsan_atomic128 v, __tsan_memory_order mo); 130 131int __tsan_atomic8_compare_exchange_weak(volatile __tsan_atomic8* a, 132 __tsan_atomic8* c, __tsan_atomic8 v, __tsan_memory_order mo, 133 __tsan_memory_order fail_mo); 134int __tsan_atomic16_compare_exchange_weak(volatile __tsan_atomic16* a, 135 __tsan_atomic16* c, __tsan_atomic16 v, __tsan_memory_order mo, 136 __tsan_memory_order fail_mo); 137int __tsan_atomic32_compare_exchange_weak(volatile __tsan_atomic32* a, 138 __tsan_atomic32* c, __tsan_atomic32 v, __tsan_memory_order mo, 139 __tsan_memory_order fail_mo); 140int __tsan_atomic64_compare_exchange_weak(volatile __tsan_atomic64* a, 141 __tsan_atomic64* c, __tsan_atomic64 v, __tsan_memory_order mo, 142 __tsan_memory_order fail_mo); 143int __tsan_atomic128_compare_exchange_weak(volatile __tsan_atomic128* a, 144 __tsan_atomic128* c, __tsan_atomic128 v, __tsan_memory_order mo, 145 __tsan_memory_order fail_mo); 146 147int __tsan_atomic8_compare_exchange_strong(volatile __tsan_atomic8* a, 148 __tsan_atomic8* c, __tsan_atomic8 v, __tsan_memory_order mo, 149 __tsan_memory_order fail_mo); 150int __tsan_atomic16_compare_exchange_strong(volatile __tsan_atomic16* a, 151 __tsan_atomic16* c, __tsan_atomic16 v, __tsan_memory_order mo, 152 __tsan_memory_order fail_mo); 153int __tsan_atomic32_compare_exchange_strong(volatile __tsan_atomic32* a, 154 __tsan_atomic32* c, __tsan_atomic32 v, __tsan_memory_order mo, 155 __tsan_memory_order fail_mo); 156int __tsan_atomic64_compare_exchange_strong(volatile __tsan_atomic64* a, 157 __tsan_atomic64* c, __tsan_atomic64 v, __tsan_memory_order mo, 158 __tsan_memory_order fail_mo); 159int __tsan_atomic128_compare_exchange_strong(volatile __tsan_atomic128* a, 160 __tsan_atomic128* c, __tsan_atomic128 v, __tsan_memory_order mo, 161 __tsan_memory_order fail_mo); 162 163__tsan_atomic8 __tsan_atomic8_compare_exchange_val( 164 volatile __tsan_atomic8* a, __tsan_atomic8 c, __tsan_atomic8 v, 165 __tsan_memory_order mo, __tsan_memory_order fail_mo); 166__tsan_atomic16 __tsan_atomic16_compare_exchange_val( 167 volatile __tsan_atomic16* a, __tsan_atomic16 c, __tsan_atomic16 v, 168 __tsan_memory_order mo, __tsan_memory_order fail_mo); 169__tsan_atomic32 __tsan_atomic32_compare_exchange_val( 170 volatile __tsan_atomic32* a, __tsan_atomic32 c, __tsan_atomic32 v, 171 __tsan_memory_order mo, __tsan_memory_order fail_mo); 172__tsan_atomic64 __tsan_atomic64_compare_exchange_val( 173 volatile __tsan_atomic64* a, __tsan_atomic64 c, __tsan_atomic64 v, 174 __tsan_memory_order mo, __tsan_memory_order fail_mo); 175__tsan_atomic128 __tsan_atomic128_compare_exchange_val( 176 volatile __tsan_atomic128* a, __tsan_atomic128 c, __tsan_atomic128 v, 177 __tsan_memory_order mo, __tsan_memory_order fail_mo); 178 179void __tsan_atomic_thread_fence(__tsan_memory_order mo); 180void __tsan_atomic_signal_fence(__tsan_memory_order mo); 181} // extern "C" 182 183#endif // #ifndef TSAN_INTERFACE_ATOMIC_H 184 185inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, 186 Atomic32 old_value, 187 Atomic32 new_value) { 188 Atomic32 cmp = old_value; 189 __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value, 190 __tsan_memory_order_relaxed, __tsan_memory_order_relaxed); 191 return cmp; 192} 193 194inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, 195 Atomic32 new_value) { 196 return __tsan_atomic32_exchange(ptr, new_value, 197 __tsan_memory_order_relaxed); 198} 199 200inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr, 201 Atomic32 new_value) { 202 return __tsan_atomic32_exchange(ptr, new_value, 203 __tsan_memory_order_acquire); 204} 205 206inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr, 207 Atomic32 new_value) { 208 return __tsan_atomic32_exchange(ptr, new_value, 209 __tsan_memory_order_release); 210} 211 212inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, 213 Atomic32 increment) { 214 return increment + __tsan_atomic32_fetch_add(ptr, increment, 215 __tsan_memory_order_relaxed); 216} 217 218inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, 219 Atomic32 increment) { 220 return increment + __tsan_atomic32_fetch_add(ptr, increment, 221 __tsan_memory_order_acq_rel); 222} 223 224inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, 225 Atomic32 old_value, 226 Atomic32 new_value) { 227 Atomic32 cmp = old_value; 228 __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value, 229 __tsan_memory_order_acquire, __tsan_memory_order_acquire); 230 return cmp; 231} 232 233inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, 234 Atomic32 old_value, 235 Atomic32 new_value) { 236 Atomic32 cmp = old_value; 237 __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value, 238 __tsan_memory_order_release, __tsan_memory_order_relaxed); 239 return cmp; 240} 241 242inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) { 243 __tsan_atomic8_store(ptr, value, __tsan_memory_order_relaxed); 244} 245 246inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { 247 __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed); 248} 249 250inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { 251 __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed); 252 __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); 253} 254 255inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { 256 __tsan_atomic32_store(ptr, value, __tsan_memory_order_release); 257} 258 259inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) { 260 return __tsan_atomic8_load(ptr, __tsan_memory_order_relaxed); 261} 262 263inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { 264 return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed); 265} 266 267inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { 268 return __tsan_atomic32_load(ptr, __tsan_memory_order_acquire); 269} 270 271inline Atomic32 Release_Load(volatile const Atomic32* ptr) { 272 __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); 273 return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed); 274} 275 276inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, 277 Atomic64 old_value, 278 Atomic64 new_value) { 279 Atomic64 cmp = old_value; 280 __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value, 281 __tsan_memory_order_relaxed, __tsan_memory_order_relaxed); 282 return cmp; 283} 284 285inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, 286 Atomic64 new_value) { 287 return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_relaxed); 288} 289 290inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr, 291 Atomic64 new_value) { 292 return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_acquire); 293} 294 295inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr, 296 Atomic64 new_value) { 297 return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_release); 298} 299 300inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, 301 Atomic64 increment) { 302 return increment + __tsan_atomic64_fetch_add(ptr, increment, 303 __tsan_memory_order_relaxed); 304} 305 306inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, 307 Atomic64 increment) { 308 return increment + __tsan_atomic64_fetch_add(ptr, increment, 309 __tsan_memory_order_acq_rel); 310} 311 312inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { 313 __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed); 314} 315 316inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { 317 __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed); 318 __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); 319} 320 321inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { 322 __tsan_atomic64_store(ptr, value, __tsan_memory_order_release); 323} 324 325inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { 326 return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed); 327} 328 329inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { 330 return __tsan_atomic64_load(ptr, __tsan_memory_order_acquire); 331} 332 333inline Atomic64 Release_Load(volatile const Atomic64* ptr) { 334 __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); 335 return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed); 336} 337 338inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, 339 Atomic64 old_value, 340 Atomic64 new_value) { 341 Atomic64 cmp = old_value; 342 __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value, 343 __tsan_memory_order_acquire, __tsan_memory_order_acquire); 344 return cmp; 345} 346 347inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, 348 Atomic64 old_value, 349 Atomic64 new_value) { 350 Atomic64 cmp = old_value; 351 __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value, 352 __tsan_memory_order_release, __tsan_memory_order_relaxed); 353 return cmp; 354} 355 356inline void MemoryBarrier() { 357 __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst); 358} 359 360} // namespace base 361} // namespace v8 362 363#endif // V8_BASE_ATOMICOPS_INTERNALS_TSAN_H_ 364