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
Expect(const MutexSet & mset,uptr i,u64 id,bool write,u64 epoch,int count)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
TEST(MutexSet,Basic)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
TEST(MutexSet,DoubleAdd)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
TEST(MutexSet,DoubleDel)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
TEST(MutexSet,Remove)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
TEST(MutexSet,Full)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
TEST(MutexSet,Overflow)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