//===-- tsan_mutexset_test.cc ---------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file is a part of ThreadSanitizer (TSan), a race detector. // //===----------------------------------------------------------------------===// #include "tsan_mutexset.h" #include "gtest/gtest.h" namespace __tsan { static void Expect(const MutexSet &mset, uptr i, u64 id, bool write, u64 epoch, int count) { MutexSet::Desc d = mset.Get(i); EXPECT_EQ(id, d.id); EXPECT_EQ(write, d.write); EXPECT_EQ(epoch, d.epoch); EXPECT_EQ(count, d.count); } TEST(MutexSet, Basic) { MutexSet mset; EXPECT_EQ(mset.Size(), (uptr)0); mset.Add(1, true, 2); EXPECT_EQ(mset.Size(), (uptr)1); Expect(mset, 0, 1, true, 2, 1); mset.Del(1, true); EXPECT_EQ(mset.Size(), (uptr)0); mset.Add(3, true, 4); mset.Add(5, false, 6); EXPECT_EQ(mset.Size(), (uptr)2); Expect(mset, 0, 3, true, 4, 1); Expect(mset, 1, 5, false, 6, 1); mset.Del(3, true); EXPECT_EQ(mset.Size(), (uptr)1); mset.Del(5, false); EXPECT_EQ(mset.Size(), (uptr)0); } TEST(MutexSet, DoubleAdd) { MutexSet mset; mset.Add(1, true, 2); EXPECT_EQ(mset.Size(), (uptr)1); Expect(mset, 0, 1, true, 2, 1); mset.Add(1, true, 2); EXPECT_EQ(mset.Size(), (uptr)1); Expect(mset, 0, 1, true, 2, 2); mset.Del(1, true); EXPECT_EQ(mset.Size(), (uptr)1); Expect(mset, 0, 1, true, 2, 1); mset.Del(1, true); EXPECT_EQ(mset.Size(), (uptr)0); } TEST(MutexSet, DoubleDel) { MutexSet mset; mset.Add(1, true, 2); EXPECT_EQ(mset.Size(), (uptr)1); mset.Del(1, true); EXPECT_EQ(mset.Size(), (uptr)0); mset.Del(1, true); EXPECT_EQ(mset.Size(), (uptr)0); } TEST(MutexSet, Remove) { MutexSet mset; mset.Add(1, true, 2); mset.Add(1, true, 2); mset.Add(3, true, 4); mset.Add(3, true, 4); EXPECT_EQ(mset.Size(), (uptr)2); mset.Remove(1); EXPECT_EQ(mset.Size(), (uptr)1); Expect(mset, 0, 3, true, 4, 2); } TEST(MutexSet, Full) { MutexSet mset; for (uptr i = 0; i < MutexSet::kMaxSize; i++) { mset.Add(i, true, i + 1); } EXPECT_EQ(mset.Size(), MutexSet::kMaxSize); for (uptr i = 0; i < MutexSet::kMaxSize; i++) { Expect(mset, i, i, true, i + 1, 1); } for (uptr i = 0; i < MutexSet::kMaxSize; i++) { mset.Add(i, true, i + 1); } EXPECT_EQ(mset.Size(), MutexSet::kMaxSize); for (uptr i = 0; i < MutexSet::kMaxSize; i++) { Expect(mset, i, i, true, i + 1, 2); } } TEST(MutexSet, Overflow) { MutexSet mset; for (uptr i = 0; i < MutexSet::kMaxSize; i++) { mset.Add(i, true, i + 1); mset.Add(i, true, i + 1); } mset.Add(100, true, 200); EXPECT_EQ(mset.Size(), MutexSet::kMaxSize); for (uptr i = 0; i < MutexSet::kMaxSize; i++) { if (i == 0) Expect(mset, i, MutexSet::kMaxSize - 1, true, MutexSet::kMaxSize, 2); else if (i == MutexSet::kMaxSize - 1) Expect(mset, i, 100, true, 200, 1); else Expect(mset, i, i, true, i + 1, 2); } } } // namespace __tsan