Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/scudo/standalone/atomic_helpers.h
35292 views
1
//===-- atomic_helpers.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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef SCUDO_ATOMIC_H_
10
#define SCUDO_ATOMIC_H_
11
12
#include "internal_defs.h"
13
14
namespace scudo {
15
16
enum memory_order {
17
memory_order_relaxed = 0,
18
memory_order_consume = 1,
19
memory_order_acquire = 2,
20
memory_order_release = 3,
21
memory_order_acq_rel = 4,
22
memory_order_seq_cst = 5
23
};
24
static_assert(memory_order_relaxed == __ATOMIC_RELAXED, "");
25
static_assert(memory_order_consume == __ATOMIC_CONSUME, "");
26
static_assert(memory_order_acquire == __ATOMIC_ACQUIRE, "");
27
static_assert(memory_order_release == __ATOMIC_RELEASE, "");
28
static_assert(memory_order_acq_rel == __ATOMIC_ACQ_REL, "");
29
static_assert(memory_order_seq_cst == __ATOMIC_SEQ_CST, "");
30
31
struct atomic_u8 {
32
typedef u8 Type;
33
volatile Type ValDoNotUse;
34
};
35
36
struct atomic_u16 {
37
typedef u16 Type;
38
volatile Type ValDoNotUse;
39
};
40
41
struct atomic_s32 {
42
typedef s32 Type;
43
volatile Type ValDoNotUse;
44
};
45
46
struct atomic_u32 {
47
typedef u32 Type;
48
volatile Type ValDoNotUse;
49
};
50
51
struct atomic_u64 {
52
typedef u64 Type;
53
// On 32-bit platforms u64 is not necessarily aligned on 8 bytes.
54
alignas(8) volatile Type ValDoNotUse;
55
};
56
57
struct atomic_uptr {
58
typedef uptr Type;
59
volatile Type ValDoNotUse;
60
};
61
62
template <typename T>
63
inline typename T::Type atomic_load(const volatile T *A, memory_order MO) {
64
DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
65
typename T::Type V;
66
__atomic_load(&A->ValDoNotUse, &V, MO);
67
return V;
68
}
69
70
template <typename T>
71
inline void atomic_store(volatile T *A, typename T::Type V, memory_order MO) {
72
DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
73
__atomic_store(&A->ValDoNotUse, &V, MO);
74
}
75
76
inline void atomic_thread_fence(memory_order) { __sync_synchronize(); }
77
78
template <typename T>
79
inline typename T::Type atomic_fetch_add(volatile T *A, typename T::Type V,
80
memory_order MO) {
81
DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
82
return __atomic_fetch_add(&A->ValDoNotUse, V, MO);
83
}
84
85
template <typename T>
86
inline typename T::Type atomic_fetch_sub(volatile T *A, typename T::Type V,
87
memory_order MO) {
88
DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
89
return __atomic_fetch_sub(&A->ValDoNotUse, V, MO);
90
}
91
92
template <typename T>
93
inline typename T::Type atomic_fetch_and(volatile T *A, typename T::Type V,
94
memory_order MO) {
95
DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
96
return __atomic_fetch_and(&A->ValDoNotUse, V, MO);
97
}
98
99
template <typename T>
100
inline typename T::Type atomic_fetch_or(volatile T *A, typename T::Type V,
101
memory_order MO) {
102
DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
103
return __atomic_fetch_or(&A->ValDoNotUse, V, MO);
104
}
105
106
template <typename T>
107
inline typename T::Type atomic_exchange(volatile T *A, typename T::Type V,
108
memory_order MO) {
109
DCHECK(!(reinterpret_cast<uptr>(A) % sizeof(*A)));
110
typename T::Type R;
111
__atomic_exchange(&A->ValDoNotUse, &V, &R, MO);
112
return R;
113
}
114
115
template <typename T>
116
inline bool atomic_compare_exchange_strong(volatile T *A, typename T::Type *Cmp,
117
typename T::Type Xchg,
118
memory_order MO) {
119
return __atomic_compare_exchange(&A->ValDoNotUse, Cmp, &Xchg, false, MO,
120
__ATOMIC_RELAXED);
121
}
122
123
// Clutter-reducing helpers.
124
125
template <typename T>
126
inline typename T::Type atomic_load_relaxed(const volatile T *A) {
127
return atomic_load(A, memory_order_relaxed);
128
}
129
130
template <typename T>
131
inline void atomic_store_relaxed(volatile T *A, typename T::Type V) {
132
atomic_store(A, V, memory_order_relaxed);
133
}
134
135
template <typename T>
136
inline typename T::Type
137
atomic_compare_exchange_strong(volatile T *A, typename T::Type Cmp,
138
typename T::Type Xchg, memory_order MO) {
139
atomic_compare_exchange_strong(A, &Cmp, Xchg, MO);
140
return Cmp;
141
}
142
143
} // namespace scudo
144
145
#endif // SCUDO_ATOMIC_H_
146
147