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

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

Issue 1343883004: Add barriers to atomic utils. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix test expectations Created 5 years, 3 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 | « no previous file | test/unittests/atomic-utils-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_ATOMIC_UTILS_H_ 5 #ifndef V8_ATOMIC_UTILS_H_
6 #define V8_ATOMIC_UTILS_H_ 6 #define V8_ATOMIC_UTILS_H_
7 7
8 #include <limits.h> 8 #include <limits.h>
9 9
10 #include "src/base/atomicops.h" 10 #include "src/base/atomicops.h"
11 #include "src/base/macros.h" 11 #include "src/base/macros.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 template <class T> 16 template <class T>
17 class AtomicNumber { 17 class AtomicNumber {
18 public: 18 public:
19 AtomicNumber() : value_(0) {} 19 AtomicNumber() : value_(0) {}
20 explicit AtomicNumber(T initial) : value_(initial) {} 20 explicit AtomicNumber(T initial) : value_(initial) {}
21 21
22 V8_INLINE void Increment(T increment) { 22 V8_INLINE void Increment(T increment) {
23 base::NoBarrier_AtomicIncrement(&value_, 23 base::Barrier_AtomicIncrement(&value_,
24 static_cast<base::AtomicWord>(increment)); 24 static_cast<base::AtomicWord>(increment));
25 } 25 }
26 26
27 V8_INLINE T Value() { return static_cast<T>(base::NoBarrier_Load(&value_)); } 27 V8_INLINE T Value() { return static_cast<T>(base::Acquire_Load(&value_)); }
28 28
29 V8_INLINE void SetValue(T new_value) { 29 V8_INLINE void SetValue(T new_value) {
30 base::NoBarrier_Store(&value_, static_cast<base::AtomicWord>(new_value)); 30 base::Release_Store(&value_, static_cast<base::AtomicWord>(new_value));
31 } 31 }
32 32
33 private: 33 private:
34 STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord)); 34 STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord));
35 35
36 base::AtomicWord value_; 36 base::AtomicWord value_;
37 }; 37 };
38 38
39 39
40 // Flag using T atomically. Also accepts void* as T. 40 // Flag using T atomically. Also accepts void* as T.
41 template <typename T> 41 template <typename T>
42 class AtomicValue { 42 class AtomicValue {
43 public: 43 public:
44 explicit AtomicValue(T initial) 44 explicit AtomicValue(T initial)
45 : value_(cast_helper<T>::to_storage_type(initial)) {} 45 : value_(cast_helper<T>::to_storage_type(initial)) {}
46 46
47 V8_INLINE T Value() { 47 V8_INLINE T Value() {
48 return cast_helper<T>::to_return_type(base::NoBarrier_Load(&value_)); 48 return cast_helper<T>::to_return_type(base::Acquire_Load(&value_));
49 } 49 }
50 50
51 V8_INLINE bool TrySetValue(T old_value, T new_value) { 51 V8_INLINE bool TrySetValue(T old_value, T new_value) {
52 return base::NoBarrier_CompareAndSwap( 52 return base::Release_CompareAndSwap(
53 &value_, cast_helper<T>::to_storage_type(old_value), 53 &value_, cast_helper<T>::to_storage_type(old_value),
54 cast_helper<T>::to_storage_type(new_value)) == 54 cast_helper<T>::to_storage_type(new_value)) ==
55 cast_helper<T>::to_storage_type(old_value); 55 cast_helper<T>::to_storage_type(old_value);
56 } 56 }
57 57
58 V8_INLINE T /*old_value*/ SetValue(T new_value) { 58 V8_INLINE void SetValue(T new_value) {
59 return cast_helper<T>::to_return_type(base::NoBarrier_AtomicExchange( 59 base::Release_Store(&value_, cast_helper<T>::to_storage_type(new_value));
60 &value_, cast_helper<T>::to_storage_type(new_value)));
61 } 60 }
62 61
63 private: 62 private:
64 STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord)); 63 STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord));
65 64
66 template <typename S> 65 template <typename S>
67 struct cast_helper { 66 struct cast_helper {
68 static base::AtomicWord to_storage_type(S value) { 67 static base::AtomicWord to_storage_type(S value) {
69 return static_cast<base::AtomicWord>(value); 68 return static_cast<base::AtomicWord>(value);
70 } 69 }
(...skipping 24 matching lines...) Expand all
95 // Example: 94 // Example:
96 // enum E { kA, kB, kC, kLastValue = kC }; 95 // enum E { kA, kB, kC, kLastValue = kC };
97 template <class E> 96 template <class E>
98 class AtomicEnumSet { 97 class AtomicEnumSet {
99 public: 98 public:
100 explicit AtomicEnumSet(base::AtomicWord bits = 0) : bits_(bits) {} 99 explicit AtomicEnumSet(base::AtomicWord bits = 0) : bits_(bits) {}
101 100
102 bool IsEmpty() const { return ToIntegral() == 0; } 101 bool IsEmpty() const { return ToIntegral() == 0; }
103 102
104 bool Contains(E element) const { return (ToIntegral() & Mask(element)) != 0; } 103 bool Contains(E element) const { return (ToIntegral() & Mask(element)) != 0; }
105
106 bool ContainsAnyOf(const AtomicEnumSet& set) const { 104 bool ContainsAnyOf(const AtomicEnumSet& set) const {
107 return (ToIntegral() & set.ToIntegral()) != 0; 105 return (ToIntegral() & set.ToIntegral()) != 0;
108 } 106 }
109 107
110 void RemoveAll() { base::NoBarrier_Store(&bits_, 0); } 108 void RemoveAll() { base::Release_Store(&bits_, 0); }
111 109
112 bool operator==(const AtomicEnumSet& set) const { 110 bool operator==(const AtomicEnumSet& set) const {
113 return ToIntegral() == set.ToIntegral(); 111 return ToIntegral() == set.ToIntegral();
114 } 112 }
115 113
116 bool operator!=(const AtomicEnumSet& set) const { 114 bool operator!=(const AtomicEnumSet& set) const {
117 return ToIntegral() != set.ToIntegral(); 115 return ToIntegral() != set.ToIntegral();
118 } 116 }
119 117
120 AtomicEnumSet<E> operator|(const AtomicEnumSet& set) const { 118 AtomicEnumSet<E> operator|(const AtomicEnumSet& set) const {
(...skipping 25 matching lines...) Expand all
146 ATOMIC_SET_WRITE(&, set.ToIntegral()); 144 ATOMIC_SET_WRITE(&, set.ToIntegral());
147 } 145 }
148 146
149 #undef ATOMIC_SET_OP 147 #undef ATOMIC_SET_OP
150 148
151 private: 149 private:
152 // Check whether there's enough storage to hold E. 150 // Check whether there's enough storage to hold E.
153 STATIC_ASSERT(E::kLastValue < (sizeof(base::AtomicWord) * CHAR_BIT)); 151 STATIC_ASSERT(E::kLastValue < (sizeof(base::AtomicWord) * CHAR_BIT));
154 152
155 V8_INLINE base::AtomicWord ToIntegral() const { 153 V8_INLINE base::AtomicWord ToIntegral() const {
156 return base::NoBarrier_Load(&bits_); 154 return base::Acquire_Load(&bits_);
157 } 155 }
158 156
159 V8_INLINE base::AtomicWord Mask(E element) const { 157 V8_INLINE base::AtomicWord Mask(E element) const {
160 return static_cast<base::AtomicWord>(1) << element; 158 return static_cast<base::AtomicWord>(1) << element;
161 } 159 }
162 160
163 base::AtomicWord bits_; 161 base::AtomicWord bits_;
164 }; 162 };
165 163
166 } // namespace internal 164 } // namespace internal
167 } // namespace v8 165 } // namespace v8
168 166
169 #endif // #define V8_ATOMIC_UTILS_H_ 167 #endif // #define V8_ATOMIC_UTILS_H_
OLDNEW
« no previous file with comments | « no previous file | test/unittests/atomic-utils-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698