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