// Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "src/base/atomic-utils.h" #include "testing/gtest/include/gtest/gtest.h" namespace v8 { namespace base { TEST(AtomicNumber, Constructor) { // Test some common types. AtomicNumber zero_int; AtomicNumber zero_size_t; AtomicNumber zero_intptr_t; EXPECT_EQ(0, zero_int.Value()); EXPECT_EQ(0U, zero_size_t.Value()); EXPECT_EQ(0, zero_intptr_t.Value()); } TEST(AtomicNumber, Value) { AtomicNumber a(1); EXPECT_EQ(1, a.Value()); AtomicNumber b(-1); EXPECT_EQ(-1, b.Value()); AtomicNumber c(1); EXPECT_EQ(1U, c.Value()); AtomicNumber d(static_cast(-1)); EXPECT_EQ(std::numeric_limits::max(), d.Value()); } TEST(AtomicNumber, SetValue) { AtomicNumber a(1); a.SetValue(-1); EXPECT_EQ(-1, a.Value()); } TEST(AtomicNumber, Increment) { AtomicNumber a(std::numeric_limits::max()); a.Increment(1); EXPECT_EQ(std::numeric_limits::min(), a.Value()); // Check that potential signed-ness of the underlying storage has no impact // on unsigned types. AtomicNumber b(std::numeric_limits::max()); b.Increment(1); EXPECT_EQ(static_cast(std::numeric_limits::max()) + 1, b.Value()); // Should work as decrement as well. AtomicNumber c(1); c.Increment(-1); EXPECT_EQ(0U, c.Value()); c.Increment(-1); EXPECT_EQ(std::numeric_limits::max(), c.Value()); } TEST(AtomicNumber, Decrement) { AtomicNumber a(std::numeric_limits::max()); a.Increment(1); EXPECT_EQ(0, a.Value()); a.Decrement(1); EXPECT_EQ(std::numeric_limits::max(), a.Value()); } TEST(AtomicNumber, OperatorAdditionAssignment) { AtomicNumber a(0u); AtomicNumber b(std::numeric_limits::max()); a += b.Value(); EXPECT_EQ(a.Value(), b.Value()); EXPECT_EQ(b.Value(), std::numeric_limits::max()); } TEST(AtomicNumber, OperatorSubtractionAssignment) { AtomicNumber a(std::numeric_limits::max()); AtomicNumber b(std::numeric_limits::max()); a -= b.Value(); EXPECT_EQ(a.Value(), 0u); EXPECT_EQ(b.Value(), std::numeric_limits::max()); } namespace { enum TestFlag { kA, kB, kC, }; } // namespace TEST(AtomicValue, Initial) { AtomicValue a(kA); EXPECT_EQ(TestFlag::kA, a.Value()); } TEST(AtomicValue, TrySetValue) { AtomicValue a(kA); EXPECT_FALSE(a.TrySetValue(kB, kC)); EXPECT_TRUE(a.TrySetValue(kA, kC)); EXPECT_EQ(TestFlag::kC, a.Value()); } TEST(AtomicValue, SetValue) { AtomicValue a(kB); a.SetValue(kC); EXPECT_EQ(TestFlag::kC, a.Value()); } TEST(AtomicValue, WithVoidStar) { AtomicValue a(nullptr); AtomicValue dummy(nullptr); EXPECT_EQ(nullptr, a.Value()); a.SetValue(&a); EXPECT_EQ(&a, a.Value()); EXPECT_FALSE(a.TrySetValue(nullptr, &dummy)); EXPECT_TRUE(a.TrySetValue(&a, &dummy)); EXPECT_EQ(&dummy, a.Value()); } namespace { enum TestSetValue { kAA, kBB, kCC, kLastValue = kCC }; } // namespace TEST(AtomicEnumSet, Constructor) { AtomicEnumSet a; EXPECT_TRUE(a.IsEmpty()); EXPECT_FALSE(a.Contains(kAA)); } TEST(AtomicEnumSet, AddSingle) { AtomicEnumSet a; a.Add(kAA); EXPECT_FALSE(a.IsEmpty()); EXPECT_TRUE(a.Contains(kAA)); EXPECT_FALSE(a.Contains(kBB)); EXPECT_FALSE(a.Contains(kCC)); } TEST(AtomicEnumSet, AddOtherSet) { AtomicEnumSet a; AtomicEnumSet b; a.Add(kAA); EXPECT_FALSE(a.IsEmpty()); EXPECT_TRUE(b.IsEmpty()); b.Add(a); EXPECT_FALSE(b.IsEmpty()); EXPECT_TRUE(a.Contains(kAA)); EXPECT_TRUE(b.Contains(kAA)); } TEST(AtomicEnumSet, RemoveSingle) { AtomicEnumSet a; a.Add(kAA); a.Add(kBB); EXPECT_TRUE(a.Contains(kAA)); EXPECT_TRUE(a.Contains(kBB)); a.Remove(kAA); EXPECT_FALSE(a.Contains(kAA)); EXPECT_TRUE(a.Contains(kBB)); } TEST(AtomicEnumSet, RemoveOtherSet) { AtomicEnumSet a; AtomicEnumSet b; a.Add(kAA); a.Add(kBB); b.Add(kBB); a.Remove(b); EXPECT_TRUE(a.Contains(kAA)); EXPECT_FALSE(a.Contains(kBB)); EXPECT_FALSE(a.Contains(kCC)); } TEST(AtomicEnumSet, RemoveEmptySet) { AtomicEnumSet a; AtomicEnumSet b; a.Add(kAA); a.Add(kBB); EXPECT_TRUE(a.Contains(kAA)); EXPECT_TRUE(a.Contains(kBB)); EXPECT_FALSE(a.Contains(kCC)); EXPECT_TRUE(b.IsEmpty()); a.Remove(b); EXPECT_TRUE(a.Contains(kAA)); EXPECT_TRUE(a.Contains(kBB)); EXPECT_FALSE(a.Contains(kCC)); } TEST(AtomicEnumSet, Intersect) { AtomicEnumSet a; AtomicEnumSet b; a.Add(kAA); b.Add(kCC); a.Intersect(b); EXPECT_TRUE(a.IsEmpty()); } TEST(AtomicEnumSet, ContainsAnyOf) { AtomicEnumSet a; AtomicEnumSet b; a.Add(kAA); b.Add(kCC); EXPECT_FALSE(a.ContainsAnyOf(b)); b.Add(kAA); EXPECT_TRUE(a.ContainsAnyOf(b)); } TEST(AtomicEnumSet, Equality) { AtomicEnumSet a; AtomicEnumSet b; a.Add(kAA); EXPECT_FALSE(a == b); EXPECT_TRUE(a != b); b.Add(kAA); EXPECT_TRUE(a == b); EXPECT_FALSE(a != b); } } // namespace base } // namespace v8