1// Copyright 2014 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#include <limits.h>
6
7#include "src/atomic-utils.h"
8#include "testing/gtest/include/gtest/gtest.h"
9
10namespace v8 {
11namespace internal {
12
13TEST(AtomicNumber, Constructor) {
14  // Test some common types.
15  AtomicNumber<int> zero_int;
16  AtomicNumber<size_t> zero_size_t;
17  AtomicNumber<intptr_t> zero_intptr_t;
18  EXPECT_EQ(0, zero_int.Value());
19  EXPECT_EQ(0U, zero_size_t.Value());
20  EXPECT_EQ(0, zero_intptr_t.Value());
21}
22
23
24TEST(AtomicNumber, Value) {
25  AtomicNumber<int> a(1);
26  EXPECT_EQ(1, a.Value());
27  AtomicNumber<int> b(-1);
28  EXPECT_EQ(-1, b.Value());
29  AtomicNumber<size_t> c(1);
30  EXPECT_EQ(1U, c.Value());
31  AtomicNumber<size_t> d(static_cast<size_t>(-1));
32  EXPECT_EQ(std::numeric_limits<size_t>::max(), d.Value());
33}
34
35
36TEST(AtomicNumber, SetValue) {
37  AtomicNumber<int> a(1);
38  a.SetValue(-1);
39  EXPECT_EQ(-1, a.Value());
40}
41
42
43TEST(AtomicNumber, Increment) {
44  AtomicNumber<int> a(std::numeric_limits<int>::max());
45  a.Increment(1);
46  EXPECT_EQ(std::numeric_limits<int>::min(), a.Value());
47  // Check that potential signed-ness of the underlying storage has no impact
48  // on unsigned types.
49  AtomicNumber<size_t> b(std::numeric_limits<intptr_t>::max());
50  b.Increment(1);
51  EXPECT_EQ(static_cast<size_t>(std::numeric_limits<intptr_t>::max()) + 1,
52            b.Value());
53  // Should work as decrement as well.
54  AtomicNumber<size_t> c(1);
55  c.Increment(-1);
56  EXPECT_EQ(0U, c.Value());
57  c.Increment(-1);
58  EXPECT_EQ(std::numeric_limits<size_t>::max(), c.Value());
59}
60
61
62namespace {
63
64enum TestFlag {
65  kA,
66  kB,
67  kC,
68};
69
70}  // namespace
71
72
73TEST(AtomicValue, Initial) {
74  AtomicValue<TestFlag> a(kA);
75  EXPECT_EQ(TestFlag::kA, a.Value());
76}
77
78
79TEST(AtomicValue, TrySetValue) {
80  AtomicValue<TestFlag> a(kA);
81  EXPECT_FALSE(a.TrySetValue(kB, kC));
82  EXPECT_TRUE(a.TrySetValue(kA, kC));
83  EXPECT_EQ(TestFlag::kC, a.Value());
84}
85
86
87TEST(AtomicValue, SetValue) {
88  AtomicValue<TestFlag> a(kB);
89  a.SetValue(kC);
90  EXPECT_EQ(TestFlag::kC, a.Value());
91}
92
93
94TEST(AtomicValue, WithVoidStar) {
95  AtomicValue<void*> a(nullptr);
96  AtomicValue<void*> dummy(nullptr);
97  EXPECT_EQ(nullptr, a.Value());
98  a.SetValue(&a);
99  EXPECT_EQ(&a, a.Value());
100  EXPECT_FALSE(a.TrySetValue(nullptr, &dummy));
101  EXPECT_TRUE(a.TrySetValue(&a, &dummy));
102  EXPECT_EQ(&dummy, a.Value());
103}
104
105
106namespace {
107
108enum TestSetValue { kAA, kBB, kCC, kLastValue = kCC };
109
110}  // namespace
111
112
113TEST(AtomicEnumSet, Constructor) {
114  AtomicEnumSet<TestSetValue> a;
115  EXPECT_TRUE(a.IsEmpty());
116  EXPECT_FALSE(a.Contains(kAA));
117}
118
119
120TEST(AtomicEnumSet, AddSingle) {
121  AtomicEnumSet<TestSetValue> a;
122  a.Add(kAA);
123  EXPECT_FALSE(a.IsEmpty());
124  EXPECT_TRUE(a.Contains(kAA));
125  EXPECT_FALSE(a.Contains(kBB));
126  EXPECT_FALSE(a.Contains(kCC));
127}
128
129
130TEST(AtomicEnumSet, AddOtherSet) {
131  AtomicEnumSet<TestSetValue> a;
132  AtomicEnumSet<TestSetValue> b;
133  a.Add(kAA);
134  EXPECT_FALSE(a.IsEmpty());
135  EXPECT_TRUE(b.IsEmpty());
136  b.Add(a);
137  EXPECT_FALSE(b.IsEmpty());
138  EXPECT_TRUE(a.Contains(kAA));
139  EXPECT_TRUE(b.Contains(kAA));
140}
141
142
143TEST(AtomicEnumSet, RemoveSingle) {
144  AtomicEnumSet<TestSetValue> a;
145  a.Add(kAA);
146  a.Add(kBB);
147  EXPECT_TRUE(a.Contains(kAA));
148  EXPECT_TRUE(a.Contains(kBB));
149  a.Remove(kAA);
150  EXPECT_FALSE(a.Contains(kAA));
151  EXPECT_TRUE(a.Contains(kBB));
152}
153
154
155TEST(AtomicEnumSet, RemoveOtherSet) {
156  AtomicEnumSet<TestSetValue> a;
157  AtomicEnumSet<TestSetValue> b;
158  a.Add(kAA);
159  a.Add(kBB);
160  b.Add(kBB);
161  a.Remove(b);
162  EXPECT_TRUE(a.Contains(kAA));
163  EXPECT_FALSE(a.Contains(kBB));
164  EXPECT_FALSE(a.Contains(kCC));
165}
166
167
168TEST(AtomicEnumSet, RemoveEmptySet) {
169  AtomicEnumSet<TestSetValue> a;
170  AtomicEnumSet<TestSetValue> b;
171  a.Add(kAA);
172  a.Add(kBB);
173  EXPECT_TRUE(a.Contains(kAA));
174  EXPECT_TRUE(a.Contains(kBB));
175  EXPECT_FALSE(a.Contains(kCC));
176  EXPECT_TRUE(b.IsEmpty());
177  a.Remove(b);
178  EXPECT_TRUE(a.Contains(kAA));
179  EXPECT_TRUE(a.Contains(kBB));
180  EXPECT_FALSE(a.Contains(kCC));
181}
182
183
184TEST(AtomicEnumSet, Intersect) {
185  AtomicEnumSet<TestSetValue> a;
186  AtomicEnumSet<TestSetValue> b;
187  a.Add(kAA);
188  b.Add(kCC);
189  a.Intersect(b);
190  EXPECT_TRUE(a.IsEmpty());
191}
192
193
194TEST(AtomicEnumSet, ContainsAnyOf) {
195  AtomicEnumSet<TestSetValue> a;
196  AtomicEnumSet<TestSetValue> b;
197  a.Add(kAA);
198  b.Add(kCC);
199  EXPECT_FALSE(a.ContainsAnyOf(b));
200  b.Add(kAA);
201  EXPECT_TRUE(a.ContainsAnyOf(b));
202}
203
204
205TEST(AtomicEnumSet, Equality) {
206  AtomicEnumSet<TestSetValue> a;
207  AtomicEnumSet<TestSetValue> b;
208  a.Add(kAA);
209  EXPECT_FALSE(a == b);
210  EXPECT_TRUE(a != b);
211  b.Add(kAA);
212  EXPECT_TRUE(a == b);
213  EXPECT_FALSE(a != b);
214}
215
216}  // namespace internal
217}  // namespace v8
218