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

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

Issue 1324153003: Add template parameter and unittests to atomic utils. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | src/heap/heap.h » ('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>
Michael Lippautz 2015/09/04 11:09:32 I don't think we need the storage type, as it shou
16 class AtomicValue { 17 class AtomicValue {
Michael Lippautz 2015/09/04 13:03:52 This one is now AtomicNumber
17 public: 18 public:
18 AtomicValue() : value_(0) {} 19 AtomicValue() : value_(0) {}
19 explicit AtomicValue(base::AtomicWord initial) : value_(initial) {} 20 explicit AtomicValue(T initial) : value_(initial) {}
20 21
21 V8_INLINE void Increment(base::AtomicWord increment) { 22 V8_INLINE void Increment(T increment) {
22 base::NoBarrier_AtomicIncrement(&value_, increment); 23 base::NoBarrier_AtomicIncrement(&value_,
24 static_cast<base::AtomicWord>(increment));
23 } 25 }
24 26
25 V8_INLINE base::AtomicWord Value() { return base::NoBarrier_Load(&value_); } 27 V8_INLINE T Value() { return static_cast<T>(base::NoBarrier_Load(&value_)); }
26 28
27 V8_INLINE void SetValue(base::AtomicWord new_value) { 29 V8_INLINE void SetValue(T new_value) {
28 base::NoBarrier_Store(&value_, new_value); 30 base::NoBarrier_Store(&value_, static_cast<base::AtomicWord>(new_value));
29 } 31 }
30 32
31 private: 33 private:
34 STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord));
35
32 base::AtomicWord value_; 36 base::AtomicWord value_;
33 }; 37 };
34 38
35 39
36 // See utils.h for EnumSet. Storage is always base::AtomicWord. 40 // See utils.h for EnumSet. Storage is always base::AtomicWord.
37 // Requirements on E: 41 // Requirements on E:
38 // - No explicit values. 42 // - No explicit values.
39 // - E::kLastValue defined to be the last actually used value. 43 // - E::kLastValue defined to be the last actually used value.
40 // 44 //
41 // Example: 45 // Example:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 do { \ 79 do { \
76 old = base::Acquire_Load(&bits_); \ 80 old = base::Acquire_Load(&bits_); \
77 } while (base::Release_CompareAndSwap(&bits_, old, old OP NEW_VAL) != \ 81 } while (base::Release_CompareAndSwap(&bits_, old, old OP NEW_VAL) != \
78 old); \ 82 old); \
79 } while (false) 83 } while (false)
80 84
81 void Add(E element) { ATOMIC_SET_WRITE(|, Mask(element)); } 85 void Add(E element) { ATOMIC_SET_WRITE(|, Mask(element)); }
82 86
83 void Add(const AtomicEnumSet& set) { ATOMIC_SET_WRITE(|, set.ToIntegral()); } 87 void Add(const AtomicEnumSet& set) { ATOMIC_SET_WRITE(|, set.ToIntegral()); }
84 88
85 void Remove(E element) { ATOMIC_SET_WRITE(&, Mask(element)); } 89 void Remove(E element) { ATOMIC_SET_WRITE(&, ~Mask(element)); }
Michael Lippautz 2015/09/04 11:09:32 *duck*
86 90
87 void Remove(const AtomicEnumSet& set) { 91 void Remove(const AtomicEnumSet& set) {
88 ATOMIC_SET_WRITE(&, ~set.ToIntegral()); 92 ATOMIC_SET_WRITE(&, ~set.ToIntegral());
89 } 93 }
90 94
91 void Intersect(const AtomicEnumSet& set) { 95 void Intersect(const AtomicEnumSet& set) {
92 ATOMIC_SET_WRITE(&, set.ToIntegral()); 96 ATOMIC_SET_WRITE(&, set.ToIntegral());
93 } 97 }
94 98
95 #undef ATOMIC_SET_OP 99 #undef ATOMIC_SET_OP
96 100
97 private: 101 private:
98 // Check whether there's enough storage to hold E. 102 // Check whether there's enough storage to hold E.
99 STATIC_ASSERT(E::kLastValue < (sizeof(base::AtomicWord) * CHAR_BIT)); 103 STATIC_ASSERT(E::kLastValue < (sizeof(base::AtomicWord) * CHAR_BIT));
100 104
101 V8_INLINE base::AtomicWord ToIntegral() const { 105 V8_INLINE base::AtomicWord ToIntegral() const {
102 return base::NoBarrier_Load(&bits_); 106 return base::NoBarrier_Load(&bits_);
103 } 107 }
104 108
105 V8_INLINE base::AtomicWord Mask(E element) const { 109 V8_INLINE base::AtomicWord Mask(E element) const {
106 return static_cast<base::AtomicWord>(1) << element; 110 return static_cast<base::AtomicWord>(1) << element;
107 } 111 }
108 112
109 base::AtomicWord bits_; 113 base::AtomicWord bits_;
110 }; 114 };
111 115
112 116
113 // Flag using enums atomically. 117 // Flag using T atomically. Also accepts void* as T.
114 template <class E> 118 template <typename T>
115 class AtomicEnumFlag { 119 class AtomicFlag {
Michael Lippautz 2015/09/04 11:09:32 Maybe another name would fit better.
Michael Starzinger 2015/09/04 11:43:19 Yeah, the name is misleading. How about "AtomicVar
Michael Lippautz 2015/09/04 13:03:52 AtomicValue it is.
116 public: 120 public:
117 explicit AtomicEnumFlag(E initial) : value_(initial) {} 121 explicit AtomicFlag(T initial) : value_((base::AtomicWord)initial) {}
118 122
119 V8_INLINE E Value() { return static_cast<E>(base::NoBarrier_Load(&value_)); } 123 V8_INLINE T Value() {
124 // We cannot use static_cast to cast from AtomicWord to void*, although
125 // we guarantee that the storage is large enough.
126 return (T)(base::NoBarrier_Load(&value_));
Michael Lippautz 2015/09/04 11:09:32 This is a bit unfortunate but I think AtomicFlag<v
Michael Starzinger 2015/09/04 11:43:19 This is uncool. Need to think more about that.
Michael Lippautz 2015/09/04 13:03:52 See the new "solution" (I know this is the wrong w
127 }
120 128
121 V8_INLINE bool TrySetValue(E old_value, E new_value) { 129 V8_INLINE bool TrySetValue(T old_value, T new_value) {
122 return base::NoBarrier_CompareAndSwap( 130 return base::NoBarrier_CompareAndSwap(&value_, (base::AtomicWord)old_value,
123 &value_, static_cast<base::AtomicWord>(old_value), 131 (base::AtomicWord)new_value) ==
124 static_cast<base::AtomicWord>(new_value)) == 132 ((base::AtomicWord)old_value);
125 static_cast<base::AtomicWord>(old_value); 133 }
134
135 V8_INLINE T /*old_value*/ SetValue(T new_value) {
136 return (T)base::NoBarrier_AtomicExchange(&value_,
137 (base::AtomicWord)new_value);
126 } 138 }
127 139
128 private: 140 private:
141 STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord));
142
129 base::AtomicWord value_; 143 base::AtomicWord value_;
130 }; 144 };
131 145
132 } // namespace internal 146 } // namespace internal
133 } // namespace v8 147 } // namespace v8
134 148
135 #endif // #define V8_ATOMIC_UTILS_H_ 149 #endif // #define V8_ATOMIC_UTILS_H_
OLDNEW
« no previous file with comments | « no previous file | src/heap/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698