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

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

Issue 1310993004: Add atomic utilities: AtomicValue, AtomicEnumSet, and AtomicEnumFlag (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add new file to buildsystem files 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 | « BUILD.gn ('k') | tools/gyp/v8.gyp » ('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 class AtomicValue {
17 public:
18 AtomicValue() : value_(0) {}
19 explicit AtomicValue(base::AtomicWord initial) : value_(initial) {}
20
21 V8_INLINE void Increment(base::AtomicWord increment) {
22 base::NoBarrier_AtomicIncrement(&value_, increment);
23 }
24
25 V8_INLINE base::AtomicWord Value() { return base::NoBarrier_Load(&value_); }
26
27 V8_INLINE void SetValue(base::AtomicWord new_value) {
28 base::NoBarrier_Store(&value_, new_value);
29 }
30
31 private:
32 base::AtomicWord value_;
33 };
34
35
36 // See utils.h for EnumSet. Storage is always base::AtomicWord.
37 // Requirements on E:
38 // - No explicit values.
39 // - E::kLastValue defined to be the last actually used value.
40 //
41 // Example:
42 // enum E { kA, kB, kC, kLastValue = kC };
43 template <class E>
44 class AtomicEnumSet {
45 public:
46 explicit AtomicEnumSet(base::AtomicWord bits = 0) : bits_(bits) {}
47
48 bool IsEmpty() const { return ToIntegral() == 0; }
49
50 bool Contains(E element) const { return (ToIntegral() & Mask(element)) != 0; }
51
52 bool ContainsAnyOf(const AtomicEnumSet& set) const {
53 return (ToIntegral() & set.ToIntegral()) != 0;
54 }
55
56 void RemoveAll() { base::NoBarrier_Store(&bits_, 0); }
57
58 bool operator==(const AtomicEnumSet& set) const {
59 return ToIntegral() == set.ToIntegral();
60 }
61
62 bool operator!=(const AtomicEnumSet& set) const {
63 return ToIntegral() != set.ToIntegral();
64 }
65
66 AtomicEnumSet<E> operator|(const AtomicEnumSet& set) const {
67 return AtomicEnumSet<E>(ToIntegral() | set.ToIntegral());
68 }
69
70 // The following operations modify the underlying storage.
71
72 #define ATOMIC_SET_WRITE(OP, NEW_VAL) \
73 do { \
74 base::AtomicWord old; \
75 do { \
76 old = base::Acquire_Load(&bits_); \
77 } while (base::Release_CompareAndSwap(&bits_, old, old OP NEW_VAL) != \
78 old); \
79 } while (false)
80
81 void Add(E element) { ATOMIC_SET_WRITE(|, Mask(element)); }
82
83 void Add(const AtomicEnumSet& set) { ATOMIC_SET_WRITE(|, set.ToIntegral()); }
84
85 void Remove(E element) { ATOMIC_SET_WRITE(&, Mask(element)); }
86
87 void Remove(const AtomicEnumSet& set) {
88 ATOMIC_SET_WRITE(&, ~set.ToIntegral());
89 }
90
91 void Intersect(const AtomicEnumSet& set) {
92 ATOMIC_SET_WRITE(&, set.ToIntegral());
93 }
94
95 #undef ATOMIC_SET_OP
96
97 private:
98 // Check whether there's enough storage to hold E.
99 STATIC_ASSERT(E::kLastValue < (sizeof(base::AtomicWord) * CHAR_BIT));
100
101 V8_INLINE base::AtomicWord ToIntegral() const {
102 return base::NoBarrier_Load(&bits_);
103 }
104
105 V8_INLINE base::AtomicWord Mask(E element) const {
106 return static_cast<base::AtomicWord>(1) << element;
107 }
108
109 base::AtomicWord bits_;
110 };
111
112
113 // Flag using enums atomically.
114 template <class E>
115 class AtomicEnumFlag {
116 public:
117 explicit AtomicEnumFlag(E initial) : value_(initial) {}
118
119 V8_INLINE E Value() { return static_cast<E>(base::NoBarrier_Load(&value_)); }
120
121 V8_INLINE bool TrySetValue(E old_value, E new_value) {
122 return base::NoBarrier_CompareAndSwap(
123 &value_, static_cast<base::AtomicWord>(old_value),
124 static_cast<base::AtomicWord>(new_value)) ==
125 static_cast<base::AtomicWord>(old_value);
126 }
127
128 private:
129 base::AtomicWord value_;
130 };
131
132 } // namespace internal
133 } // namespace v8
134
135 #endif // #define V8_ATOMIC_UTILS_H_
OLDNEW
« no previous file with comments | « BUILD.gn ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698