Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: src/atomic-utils.h

Issue 1954603002: Move atomic-utils.h into base/ (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « BUILD.gn ('k') | src/base/atomic-utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 #ifndef V8_ATOMIC_UTILS_H_
6 #define V8_ATOMIC_UTILS_H_
7
8 #include <limits.h>
9
10 #include "src/base/atomicops.h"
11 #include "src/base/macros.h"
12
13 namespace v8 {
14 namespace internal {
15
16 template <class T>
17 class AtomicNumber {
18 public:
19 AtomicNumber() : value_(0) {}
20 explicit AtomicNumber(T initial) : value_(initial) {}
21
22 // Returns the newly set value.
23 V8_INLINE T Increment(T increment) {
24 return static_cast<T>(base::Barrier_AtomicIncrement(
25 &value_, static_cast<base::AtomicWord>(increment)));
26 }
27
28 V8_INLINE T Value() { return static_cast<T>(base::Acquire_Load(&value_)); }
29
30 V8_INLINE void SetValue(T new_value) {
31 base::Release_Store(&value_, static_cast<base::AtomicWord>(new_value));
32 }
33
34 V8_INLINE T operator=(T value) {
35 SetValue(value);
36 return value;
37 }
38
39 private:
40 STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord));
41
42 base::AtomicWord value_;
43 };
44
45
46 // Flag using T atomically. Also accepts void* as T.
47 template <typename T>
48 class AtomicValue {
49 public:
50 AtomicValue() : value_(0) {}
51
52 explicit AtomicValue(T initial)
53 : value_(cast_helper<T>::to_storage_type(initial)) {}
54
55 V8_INLINE T Value() {
56 return cast_helper<T>::to_return_type(base::Acquire_Load(&value_));
57 }
58
59 V8_INLINE bool TrySetValue(T old_value, T new_value) {
60 return base::Release_CompareAndSwap(
61 &value_, cast_helper<T>::to_storage_type(old_value),
62 cast_helper<T>::to_storage_type(new_value)) ==
63 cast_helper<T>::to_storage_type(old_value);
64 }
65
66 V8_INLINE void SetValue(T new_value) {
67 base::Release_Store(&value_, cast_helper<T>::to_storage_type(new_value));
68 }
69
70 private:
71 STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord));
72
73 template <typename S>
74 struct cast_helper {
75 static base::AtomicWord to_storage_type(S value) {
76 return static_cast<base::AtomicWord>(value);
77 }
78 static S to_return_type(base::AtomicWord value) {
79 return static_cast<S>(value);
80 }
81 };
82
83 template <typename S>
84 struct cast_helper<S*> {
85 static base::AtomicWord to_storage_type(S* value) {
86 return reinterpret_cast<base::AtomicWord>(value);
87 }
88 static S* to_return_type(base::AtomicWord value) {
89 return reinterpret_cast<S*>(value);
90 }
91 };
92
93 base::AtomicWord value_;
94 };
95
96
97 // See utils.h for EnumSet. Storage is always base::AtomicWord.
98 // Requirements on E:
99 // - No explicit values.
100 // - E::kLastValue defined to be the last actually used value.
101 //
102 // Example:
103 // enum E { kA, kB, kC, kLastValue = kC };
104 template <class E>
105 class AtomicEnumSet {
106 public:
107 explicit AtomicEnumSet(base::AtomicWord bits = 0) : bits_(bits) {}
108
109 bool IsEmpty() const { return ToIntegral() == 0; }
110
111 bool Contains(E element) const { return (ToIntegral() & Mask(element)) != 0; }
112 bool ContainsAnyOf(const AtomicEnumSet& set) const {
113 return (ToIntegral() & set.ToIntegral()) != 0;
114 }
115
116 void RemoveAll() { base::Release_Store(&bits_, 0); }
117
118 bool operator==(const AtomicEnumSet& set) const {
119 return ToIntegral() == set.ToIntegral();
120 }
121
122 bool operator!=(const AtomicEnumSet& set) const {
123 return ToIntegral() != set.ToIntegral();
124 }
125
126 AtomicEnumSet<E> operator|(const AtomicEnumSet& set) const {
127 return AtomicEnumSet<E>(ToIntegral() | set.ToIntegral());
128 }
129
130 // The following operations modify the underlying storage.
131
132 #define ATOMIC_SET_WRITE(OP, NEW_VAL) \
133 do { \
134 base::AtomicWord old; \
135 do { \
136 old = base::Acquire_Load(&bits_); \
137 } while (base::Release_CompareAndSwap(&bits_, old, old OP NEW_VAL) != \
138 old); \
139 } while (false)
140
141 void Add(E element) { ATOMIC_SET_WRITE(|, Mask(element)); }
142
143 void Add(const AtomicEnumSet& set) { ATOMIC_SET_WRITE(|, set.ToIntegral()); }
144
145 void Remove(E element) { ATOMIC_SET_WRITE(&, ~Mask(element)); }
146
147 void Remove(const AtomicEnumSet& set) {
148 ATOMIC_SET_WRITE(&, ~set.ToIntegral());
149 }
150
151 void Intersect(const AtomicEnumSet& set) {
152 ATOMIC_SET_WRITE(&, set.ToIntegral());
153 }
154
155 #undef ATOMIC_SET_OP
156
157 private:
158 // Check whether there's enough storage to hold E.
159 STATIC_ASSERT(E::kLastValue < (sizeof(base::AtomicWord) * CHAR_BIT));
160
161 V8_INLINE base::AtomicWord ToIntegral() const {
162 return base::Acquire_Load(&bits_);
163 }
164
165 V8_INLINE base::AtomicWord Mask(E element) const {
166 return static_cast<base::AtomicWord>(1) << element;
167 }
168
169 base::AtomicWord bits_;
170 };
171
172 } // namespace internal
173 } // namespace v8
174
175 #endif // #define V8_ATOMIC_UTILS_H_
OLDNEW
« no previous file with comments | « BUILD.gn ('k') | src/base/atomic-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698