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 10 namespace v8 { 11 namespace internal { 12 13 TEST(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 24 TEST(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 36 TEST(AtomicNumber, SetValue) { 37 AtomicNumber<int> a(1); 38 a.SetValue(-1); 39 EXPECT_EQ(-1, a.Value()); 40 } 41 42 43 TEST(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 62 namespace { 63 64 enum TestFlag { 65 kA, 66 kB, 67 kC, 68 }; 69 70 } // namespace 71 72 73 TEST(AtomicValue, Initial) { 74 AtomicValue<TestFlag> a(kA); 75 EXPECT_EQ(TestFlag::kA, a.Value()); 76 } 77 78 79 TEST(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 87 TEST(AtomicValue, SetValue) { 88 AtomicValue<TestFlag> a(kB); 89 a.SetValue(kC); 90 EXPECT_EQ(TestFlag::kC, a.Value()); 91 } 92 93 94 TEST(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 106 namespace { 107 108 enum TestSetValue { kAA, kBB, kCC, kLastValue = kCC }; 109 110 } // namespace 111 112 113 TEST(AtomicEnumSet, Constructor) { 114 AtomicEnumSet<TestSetValue> a; 115 EXPECT_TRUE(a.IsEmpty()); 116 EXPECT_FALSE(a.Contains(kAA)); 117 } 118 119 120 TEST(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 130 TEST(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 143 TEST(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 155 TEST(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 168 TEST(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 184 TEST(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 194 TEST(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 205 TEST(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