Path: blob/main/contrib/llvm-project/compiler-rt/lib/scudo/standalone/atomic_helpers.h
35292 views
//===-- atomic_helpers.h ----------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef SCUDO_ATOMIC_H_9#define SCUDO_ATOMIC_H_1011#include "internal_defs.h"1213namespace scudo {1415enum memory_order {16memory_order_relaxed = 0,17memory_order_consume = 1,18memory_order_acquire = 2,19memory_order_release = 3,20memory_order_acq_rel = 4,21memory_order_seq_cst = 522};23static_assert(memory_order_relaxed == __ATOMIC_RELAXED, "");24static_assert(memory_order_consume == __ATOMIC_CONSUME, "");25static_assert(memory_order_acquire == __ATOMIC_ACQUIRE, "");26static_assert(memory_order_release == __ATOMIC_RELEASE, "");27static_assert(memory_order_acq_rel == __ATOMIC_ACQ_REL, "");28static_assert(memory_order_seq_cst == __ATOMIC_SEQ_CST, "");2930struct atomic_u8 {31typedef u8 Type;32volatile Type ValDoNotUse;33};3435struct atomic_u16 {36typedef u16 Type;37volatile Type ValDoNotUse;38};3940struct atomic_s32 {41typedef s32 Type;42volatile Type ValDoNotUse;43};4445struct atomic_u32 {46typedef u32 Type;47volatile Type ValDoNotUse;48};4950struct atomic_u64 {51typedef u64 Type;52// On 32-bit platforms u64 is not necessarily aligned on 8 bytes.53alignas(8) volatile Type ValDoNotUse;54};5556struct atomic_uptr {57typedef uptr Type;58volatile Type ValDoNotUse;59};6061template <typename T>62inline typename T::Type atomic_load(const volatile T *A, memory_order MO) {63DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));64typename T::Type V;65__atomic_load(&A->ValDoNotUse, &V, MO);66return V;67}6869template <typename T>70inline void atomic_store(volatile T *A, typename T::Type V, memory_order MO) {71DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));72__atomic_store(&A->ValDoNotUse, &V, MO);73}7475inline void atomic_thread_fence(memory_order) { __sync_synchronize(); }7677template <typename T>78inline typename T::Type atomic_fetch_add(volatile T *A, typename T::Type V,79memory_order MO) {80DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));81return __atomic_fetch_add(&A->ValDoNotUse, V, MO);82}8384template <typename T>85inline typename T::Type atomic_fetch_sub(volatile T *A, typename T::Type V,86memory_order MO) {87DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));88return __atomic_fetch_sub(&A->ValDoNotUse, V, MO);89}9091template <typename T>92inline typename T::Type atomic_fetch_and(volatile T *A, typename T::Type V,93memory_order MO) {94DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));95return __atomic_fetch_and(&A->ValDoNotUse, V, MO);96}9798template <typename T>99inline typename T::Type atomic_fetch_or(volatile T *A, typename T::Type V,100memory_order MO) {101DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));102return __atomic_fetch_or(&A->ValDoNotUse, V, MO);103}104105template <typename T>106inline typename T::Type atomic_exchange(volatile T *A, typename T::Type V,107memory_order MO) {108DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));109typename T::Type R;110__atomic_exchange(&A->ValDoNotUse, &V, &R, MO);111return R;112}113114template <typename T>115inline bool atomic_compare_exchange_strong(volatile T *A, typename T::Type *Cmp,116typename T::Type Xchg,117memory_order MO) {118return __atomic_compare_exchange(&A->ValDoNotUse, Cmp, &Xchg, false, MO,119__ATOMIC_RELAXED);120}121122// Clutter-reducing helpers.123124template <typename T>125inline typename T::Type atomic_load_relaxed(const volatile T *A) {126return atomic_load(A, memory_order_relaxed);127}128129template <typename T>130inline void atomic_store_relaxed(volatile T *A, typename T::Type V) {131atomic_store(A, V, memory_order_relaxed);132}133134template <typename T>135inline typename T::Type136atomic_compare_exchange_strong(volatile T *A, typename T::Type Cmp,137typename T::Type Xchg, memory_order MO) {138atomic_compare_exchange_strong(A, &Cmp, Xchg, MO);139return Cmp;140}141142} // namespace scudo143144#endif // SCUDO_ATOMIC_H_145146147