Flutter Engine
The Flutter Engine
atomic.h
Go to the documentation of this file.
1// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_PLATFORM_ATOMIC_H_
6#define RUNTIME_PLATFORM_ATOMIC_H_
7
8#include <atomic>
9
10namespace dart {
11
12// Like std::atomic, but operations default to relaxed ordering instead of
13// sequential consistency.
14template <typename T>
16 public:
17 constexpr RelaxedAtomic() : value_() {}
18 constexpr RelaxedAtomic(T arg) : value_(arg) {} // NOLINT
19 RelaxedAtomic(const RelaxedAtomic& arg) : value_(arg) {} // NOLINT
20
21 T load(std::memory_order order = std::memory_order_relaxed) const {
22 return value_.load(order);
23 }
24 T load(std::memory_order order = std::memory_order_relaxed) const volatile {
25 return value_.load(order);
26 }
27 void store(T arg, std::memory_order order = std::memory_order_relaxed) {
28 value_.store(arg, order);
29 }
30 void store(T arg,
31 std::memory_order order = std::memory_order_relaxed) volatile {
32 value_.store(arg, order);
33 }
34
35 T fetch_add(T arg, std::memory_order order = std::memory_order_relaxed) {
36 return value_.fetch_add(arg, order);
37 }
38 T fetch_sub(T arg, std::memory_order order = std::memory_order_relaxed) {
39 return value_.fetch_sub(arg, order);
40 }
41 T fetch_or(T arg, std::memory_order order = std::memory_order_relaxed) {
42 return value_.fetch_or(arg, order);
43 }
44 T fetch_and(T arg, std::memory_order order = std::memory_order_relaxed) {
45 return value_.fetch_and(arg, order);
46 }
47
48 T exchange(T arg, std::memory_order order = std::memory_order_relaxed) {
49 return value_.exchange(arg, order);
50 }
51
53 T& expected, // NOLINT
54 T desired,
55 std::memory_order order = std::memory_order_relaxed) {
56 return value_.compare_exchange_weak(expected, desired, order, order);
57 }
59 T& expected, // NOLINT
60 T desired,
61 std::memory_order order = std::memory_order_relaxed) volatile {
62 return value_.compare_exchange_weak(expected, desired, order, order);
63 }
65 T& expected, // NOLINT
66 T desired,
67 std::memory_order order = std::memory_order_relaxed) {
68 return value_.compare_exchange_strong(expected, desired, order, order);
69 }
70
71 operator T() const { return load(); }
72 T operator=(T arg) {
73 store(arg);
74 return arg;
75 }
77 T loaded_once = arg;
78 store(loaded_once);
79 return loaded_once;
80 }
81 T operator+=(T arg) { return fetch_add(arg) + arg; }
82 T operator-=(T arg) { return fetch_sub(arg) - arg; }
83 T operator++() { return fetch_add(1) + 1; }
84 T operator--() { return fetch_sub(1) - 1; }
85 T operator++(int) { return fetch_add(1); }
86 T operator--(int) { return fetch_sub(1); }
87
88 private:
89 std::atomic<T> value_;
90};
91
92// Like std::atomic, but operations default to acquire for load, release for
93// stores, and acquire-release for read-and-updates.
94template <typename T>
96 public:
97 constexpr AcqRelAtomic() : value_() {}
98 constexpr AcqRelAtomic(T arg) : value_(arg) {} // NOLINT
99 AcqRelAtomic(const AcqRelAtomic& arg) = delete;
100
101 T load(std::memory_order order = std::memory_order_acquire) const {
102 return value_.load(order);
103 }
104 void store(T arg, std::memory_order order = std::memory_order_release) {
105 value_.store(arg, order);
106 }
107
108 T fetch_add(T arg, std::memory_order order = std::memory_order_acq_rel) {
109 return value_.fetch_add(arg, order);
110 }
111 T fetch_sub(T arg, std::memory_order order = std::memory_order_acq_rel) {
112 return value_.fetch_sub(arg, order);
113 }
114 T fetch_or(T arg, std::memory_order order = std::memory_order_acq_rel) {
115 return value_.fetch_or(arg, order);
116 }
117 T fetch_and(T arg, std::memory_order order = std::memory_order_acq_rel) {
118 return value_.fetch_and(arg, order);
119 }
120
122 T& expected, // NOLINT
123 T desired,
124 std::memory_order success_order = std::memory_order_acq_rel,
125 std::memory_order failure_order = std::memory_order_acquire) {
126 return value_.compare_exchange_weak(expected, desired, success_order,
127 failure_order);
128 }
130 T& expected, // NOLINT
131 T desired,
132 std::memory_order success_order = std::memory_order_acq_rel,
133 std::memory_order failure_order = std::memory_order_acquire) {
134 return value_.compare_exchange_strong(expected, desired, success_order,
135 failure_order);
136 }
137
138 // Require explicit loads and stores.
139 operator T() const = delete;
140 T operator=(T arg) = delete;
141 T operator=(const AcqRelAtomic& arg) = delete;
142 T operator+=(T arg) = delete;
143 T operator-=(T arg) = delete;
144
145 private:
146 std::atomic<T> value_;
147};
148
149template <typename T>
150static inline T LoadRelaxed(const T* ptr) {
151 static_assert(sizeof(std::atomic<T>) == sizeof(T));
152 return reinterpret_cast<const std::atomic<T>*>(ptr)->load(
153 std::memory_order_relaxed);
154}
155
156} // namespace dart
157
158#endif // RUNTIME_PLATFORM_ATOMIC_H_
SI T load(const P *ptr)
Definition: Transform_inl.h:98
constexpr AcqRelAtomic()
Definition: atomic.h:97
T fetch_or(T arg, std::memory_order order=std::memory_order_acq_rel)
Definition: atomic.h:114
AcqRelAtomic(const AcqRelAtomic &arg)=delete
T operator+=(T arg)=delete
T operator=(const AcqRelAtomic &arg)=delete
bool compare_exchange_weak(T &expected, T desired, std::memory_order success_order=std::memory_order_acq_rel, std::memory_order failure_order=std::memory_order_acquire)
Definition: atomic.h:121
T operator-=(T arg)=delete
T operator=(T arg)=delete
T load(std::memory_order order=std::memory_order_acquire) const
Definition: atomic.h:101
void store(T arg, std::memory_order order=std::memory_order_release)
Definition: atomic.h:104
bool compare_exchange_strong(T &expected, T desired, std::memory_order success_order=std::memory_order_acq_rel, std::memory_order failure_order=std::memory_order_acquire)
Definition: atomic.h:129
T fetch_and(T arg, std::memory_order order=std::memory_order_acq_rel)
Definition: atomic.h:117
T fetch_add(T arg, std::memory_order order=std::memory_order_acq_rel)
Definition: atomic.h:108
T fetch_sub(T arg, std::memory_order order=std::memory_order_acq_rel)
Definition: atomic.h:111
constexpr AcqRelAtomic(T arg)
Definition: atomic.h:98
void store(T arg, std::memory_order order=std::memory_order_relaxed) volatile
Definition: atomic.h:30
constexpr RelaxedAtomic()
Definition: atomic.h:17
T load(std::memory_order order=std::memory_order_relaxed) const
Definition: atomic.h:21
T operator=(T arg)
Definition: atomic.h:72
T operator++(int)
Definition: atomic.h:85
bool compare_exchange_weak(T &expected, T desired, std::memory_order order=std::memory_order_relaxed) volatile
Definition: atomic.h:58
bool compare_exchange_strong(T &expected, T desired, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:64
T operator-=(T arg)
Definition: atomic.h:82
T fetch_add(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:35
T operator--(int)
Definition: atomic.h:86
RelaxedAtomic(const RelaxedAtomic &arg)
Definition: atomic.h:19
T fetch_and(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:44
constexpr RelaxedAtomic(T arg)
Definition: atomic.h:18
T load(std::memory_order order=std::memory_order_relaxed) const volatile
Definition: atomic.h:24
bool compare_exchange_weak(T &expected, T desired, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:52
void store(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:27
T operator+=(T arg)
Definition: atomic.h:81
T exchange(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:48
T operator=(const RelaxedAtomic &arg)
Definition: atomic.h:76
T fetch_or(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:41
T fetch_sub(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:38
Definition: dart_vm.cc:33
static T LoadRelaxed(const T *ptr)
Definition: atomic.h:150
#define T
Definition: precompiler.cc:65