1 //===-- tsan_mutexset_test.cpp --------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of ThreadSanitizer (TSan), a race detector. 10 // 11 //===----------------------------------------------------------------------===// 12 #include "tsan_mutexset.h" 13 #include "gtest/gtest.h" 14 15 namespace __tsan { 16 17 static void Expect(const MutexSet &mset, uptr i, u64 id, bool write, u64 epoch, 18 int count) { 19 MutexSet::Desc d = mset.Get(i); 20 EXPECT_EQ(id, d.id); 21 EXPECT_EQ(write, d.write); 22 EXPECT_EQ(epoch, d.epoch); 23 EXPECT_EQ(count, d.count); 24 } 25 26 TEST(MutexSet, Basic) { 27 MutexSet mset; 28 EXPECT_EQ(mset.Size(), (uptr)0); 29 30 mset.Add(1, true, 2); 31 EXPECT_EQ(mset.Size(), (uptr)1); 32 Expect(mset, 0, 1, true, 2, 1); 33 mset.Del(1, true); 34 EXPECT_EQ(mset.Size(), (uptr)0); 35 36 mset.Add(3, true, 4); 37 mset.Add(5, false, 6); 38 EXPECT_EQ(mset.Size(), (uptr)2); 39 Expect(mset, 0, 3, true, 4, 1); 40 Expect(mset, 1, 5, false, 6, 1); 41 mset.Del(3, true); 42 EXPECT_EQ(mset.Size(), (uptr)1); 43 mset.Del(5, false); 44 EXPECT_EQ(mset.Size(), (uptr)0); 45 } 46 47 TEST(MutexSet, DoubleAdd) { 48 MutexSet mset; 49 mset.Add(1, true, 2); 50 EXPECT_EQ(mset.Size(), (uptr)1); 51 Expect(mset, 0, 1, true, 2, 1); 52 53 mset.Add(1, true, 2); 54 EXPECT_EQ(mset.Size(), (uptr)1); 55 Expect(mset, 0, 1, true, 2, 2); 56 57 mset.Del(1, true); 58 EXPECT_EQ(mset.Size(), (uptr)1); 59 Expect(mset, 0, 1, true, 2, 1); 60 61 mset.Del(1, true); 62 EXPECT_EQ(mset.Size(), (uptr)0); 63 } 64 65 TEST(MutexSet, DoubleDel) { 66 MutexSet mset; 67 mset.Add(1, true, 2); 68 EXPECT_EQ(mset.Size(), (uptr)1); 69 mset.Del(1, true); 70 EXPECT_EQ(mset.Size(), (uptr)0); 71 mset.Del(1, true); 72 EXPECT_EQ(mset.Size(), (uptr)0); 73 } 74 75 TEST(MutexSet, Remove) { 76 MutexSet mset; 77 mset.Add(1, true, 2); 78 mset.Add(1, true, 2); 79 mset.Add(3, true, 4); 80 mset.Add(3, true, 4); 81 EXPECT_EQ(mset.Size(), (uptr)2); 82 83 mset.Remove(1); 84 EXPECT_EQ(mset.Size(), (uptr)1); 85 Expect(mset, 0, 3, true, 4, 2); 86 } 87 88 TEST(MutexSet, Full) { 89 MutexSet mset; 90 for (uptr i = 0; i < MutexSet::kMaxSize; i++) { 91 mset.Add(i, true, i + 1); 92 } 93 EXPECT_EQ(mset.Size(), MutexSet::kMaxSize); 94 for (uptr i = 0; i < MutexSet::kMaxSize; i++) { 95 Expect(mset, i, i, true, i + 1, 1); 96 } 97 98 for (uptr i = 0; i < MutexSet::kMaxSize; i++) { 99 mset.Add(i, true, i + 1); 100 } 101 EXPECT_EQ(mset.Size(), MutexSet::kMaxSize); 102 for (uptr i = 0; i < MutexSet::kMaxSize; i++) { 103 Expect(mset, i, i, true, i + 1, 2); 104 } 105 } 106 107 TEST(MutexSet, Overflow) { 108 MutexSet mset; 109 for (uptr i = 0; i < MutexSet::kMaxSize; i++) { 110 mset.Add(i, true, i + 1); 111 mset.Add(i, true, i + 1); 112 } 113 mset.Add(100, true, 200); 114 EXPECT_EQ(mset.Size(), MutexSet::kMaxSize); 115 for (uptr i = 0; i < MutexSet::kMaxSize; i++) { 116 if (i == 0) 117 Expect(mset, i, MutexSet::kMaxSize - 1, 118 true, MutexSet::kMaxSize, 2); 119 else if (i == MutexSet::kMaxSize - 1) 120 Expect(mset, i, 100, true, 200, 1); 121 else 122 Expect(mset, i, i, true, i + 1, 2); 123 } 124 } 125 126 } // namespace __tsan 127