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
15namespace __tsan {
16
17static 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
26TEST(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
47TEST(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
65TEST(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
75TEST(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
88TEST(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
107TEST(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

source code of compiler-rt/lib/tsan/tests/unit/tsan_mutexset_test.cpp