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