brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · fded665 Raw
115 lines · c
1//===-- sanitizer_atomic_clang.h --------------------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer/AddressSanitizer runtime.10// Not intended for direct inclusion. Include sanitizer_atomic.h.11//12//===----------------------------------------------------------------------===//13 14#ifndef SANITIZER_ATOMIC_CLANG_H15#define SANITIZER_ATOMIC_CLANG_H16 17// Helper to suppress warnings related to 8-byte atomic accesses when the target18// is 32-bit AIX (where such accesses use libatomic).19#if defined(_AIX) && !defined(__powerpc64__) && defined(__clang__)20#  define SANITIZER_IGNORE_ATOMIC_ALIGNMENT_BEGIN \21    _Pragma("clang diagnostic push")              \22        _Pragma("clang diagnostic ignored \"-Watomic-alignment\"")23#  define SANITIZER_IGNORE_ATOMIC_ALIGNMENT_END _Pragma("clang diagnostic pop")24#else25#  define SANITIZER_IGNORE_ATOMIC_ALIGNMENT_BEGIN26#  define SANITIZER_IGNORE_ATOMIC_ALIGNMENT_END27#endif28 29namespace __sanitizer {30 31// We use the compiler builtin atomic operations for loads and stores, which32// generates correct code for all architectures, but may require libatomic33// on platforms where e.g. 64-bit atomics are not supported natively.34 35// See http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html36// for mappings of the memory model to different processors.37 38inline void atomic_signal_fence(memory_order mo) { __atomic_signal_fence(mo); }39 40inline void atomic_thread_fence(memory_order mo) { __atomic_thread_fence(mo); }41 42inline void proc_yield(int cnt) {43  __asm__ __volatile__("" ::: "memory");44#if defined(__i386__) || defined(__x86_64__)45  for (int i = 0; i < cnt; i++) __asm__ __volatile__("pause");46  __asm__ __volatile__("" ::: "memory");47#endif48}49 50SANITIZER_IGNORE_ATOMIC_ALIGNMENT_BEGIN51template <typename T>52inline typename T::Type atomic_load(const volatile T *a, memory_order mo) {53  DCHECK(mo == memory_order_relaxed || mo == memory_order_consume ||54         mo == memory_order_acquire || mo == memory_order_seq_cst);55  DCHECK(!((uptr)a % sizeof(*a)));56  return __atomic_load_n(&a->val_dont_use, mo);57}58 59template <typename T>60inline void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {61  DCHECK(mo == memory_order_relaxed || mo == memory_order_release ||62         mo == memory_order_seq_cst);63  DCHECK(!((uptr)a % sizeof(*a)));64  __atomic_store_n(&a->val_dont_use, v, mo);65}66 67template <typename T>68inline typename T::Type atomic_fetch_add(volatile T *a, typename T::Type v,69                                         memory_order mo) {70  DCHECK(!((uptr)a % sizeof(*a)));71  return __atomic_fetch_add(&a->val_dont_use, v, mo);72}73 74template <typename T>75inline typename T::Type atomic_fetch_sub(volatile T *a, typename T::Type v,76                                         memory_order mo) {77  (void)mo;78  DCHECK(!((uptr)a % sizeof(*a)));79  return __atomic_fetch_sub(&a->val_dont_use, v, mo);80}81 82template <typename T>83inline typename T::Type atomic_exchange(volatile T *a, typename T::Type v,84                                        memory_order mo) {85  DCHECK(!((uptr)a % sizeof(*a)));86  return __atomic_exchange_n(&a->val_dont_use, v, mo);87}88 89template <typename T>90inline bool atomic_compare_exchange_strong(volatile T *a, typename T::Type *cmp,91                                           typename T::Type xchg,92                                           memory_order mo) {93  // Transitioned from __sync_val_compare_and_swap to support targets like94  // SPARC V8 that cannot inline atomic cmpxchg.  __atomic_compare_exchange95  // can then be resolved from libatomic.  __ATOMIC_SEQ_CST is used to best96  // match the __sync builtin memory order.97  return __atomic_compare_exchange(&a->val_dont_use, cmp, &xchg, false,98                                   __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);99}100 101template <typename T>102inline bool atomic_compare_exchange_weak(volatile T *a, typename T::Type *cmp,103                                         typename T::Type xchg,104                                         memory_order mo) {105  return atomic_compare_exchange_strong(a, cmp, xchg, mo);106}107 108SANITIZER_IGNORE_ATOMIC_ALIGNMENT_END109 110}  // namespace __sanitizer111 112#undef ATOMIC_ORDER113 114#endif  // SANITIZER_ATOMIC_CLANG_H115