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
16namespace __tsan {
17
18static 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
27TEST(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
48TEST(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
66TEST(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
76TEST(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
89TEST(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
108TEST(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