xref: /llvm-project/compiler-rt/lib/tsan/tests/unit/tsan_ilist_test.cpp (revision ac2ffdef9cc8d152801ca87d81736fb1dec9cb88)
1 //===-- tsan_ilist_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_ilist.h"
13 
14 #include "gtest/gtest.h"
15 
16 namespace __tsan {
17 
18 struct Node {
19   INode node1;
20   INode node2;
21 };
22 
23 struct Parent : Node {};
24 
TEST(IList,Empty)25 TEST(IList, Empty) {
26   IList<Node, &Node::node1> list;
27   Node node;
28 
29   EXPECT_TRUE(list.Empty());
30   EXPECT_EQ(list.Size(), (size_t)0);
31   EXPECT_EQ(list.Back(), nullptr);
32   EXPECT_EQ(list.Front(), nullptr);
33   EXPECT_EQ(list.PopBack(), nullptr);
34   EXPECT_EQ(list.PopFront(), nullptr);
35   EXPECT_FALSE(list.Queued(&node));
36 }
37 
TEST(IList,OneNode)38 TEST(IList, OneNode) {
39   IList<Node, &Node::node1> list;
40   Node node;
41 
42   list.PushBack(&node);
43   EXPECT_FALSE(list.Empty());
44   EXPECT_EQ(list.Size(), (size_t)1);
45   EXPECT_EQ(list.Back(), &node);
46   EXPECT_EQ(list.Front(), &node);
47   EXPECT_TRUE(list.Queued(&node));
48   EXPECT_EQ(list.Prev(&node), nullptr);
49   EXPECT_EQ(list.Next(&node), nullptr);
50 
51   EXPECT_EQ(list.PopFront(), &node);
52   EXPECT_TRUE(list.Empty());
53   EXPECT_EQ(list.Size(), (size_t)0);
54   EXPECT_FALSE(list.Queued(&node));
55 }
56 
TEST(IList,MultipleNodes)57 TEST(IList, MultipleNodes) {
58   IList<Node, &Node::node1> list;
59   Node nodes[3];
60 
61   list.PushBack(&nodes[1]);
62   list.PushBack(&nodes[0]);
63   list.PushFront(&nodes[2]);
64 
65   EXPECT_EQ(list.Size(), (size_t)3);
66   EXPECT_EQ(list.Back(), &nodes[0]);
67   EXPECT_EQ(list.Front(), &nodes[2]);
68 
69   EXPECT_EQ(list.Next(&nodes[0]), nullptr);
70   EXPECT_EQ(list.Prev(&nodes[0]), &nodes[1]);
71 
72   EXPECT_EQ(list.Next(&nodes[1]), &nodes[0]);
73   EXPECT_EQ(list.Prev(&nodes[1]), &nodes[2]);
74 
75   EXPECT_EQ(list.Next(&nodes[2]), &nodes[1]);
76   EXPECT_EQ(list.Prev(&nodes[2]), nullptr);
77 
78   EXPECT_EQ(list.PopBack(), &nodes[0]);
79   EXPECT_EQ(list.PopFront(), &nodes[2]);
80   EXPECT_EQ(list.PopFront(), &nodes[1]);
81   EXPECT_TRUE(list.Empty());
82 }
83 
TEST(IList,TwoLists)84 TEST(IList, TwoLists) {
85   IList<Node, &Node::node1> list1;
86   IList<Node, &Node::node2, Parent> list2;
87   Parent nodes[3];
88 
89   list1.PushBack(&nodes[2]);
90   list1.PushBack(&nodes[1]);
91   list1.PushBack(&nodes[0]);
92 
93   list2.PushFront(&nodes[1]);
94 
95   EXPECT_EQ(list1.Size(), (size_t)3);
96   EXPECT_TRUE(list1.Queued(&nodes[0]));
97   EXPECT_TRUE(list1.Queued(&nodes[1]));
98   EXPECT_TRUE(list1.Queued(&nodes[2]));
99 
100   EXPECT_EQ(list2.Size(), (size_t)1);
101   EXPECT_FALSE(list2.Queued(&nodes[0]));
102   EXPECT_TRUE(list2.Queued(&nodes[1]));
103   EXPECT_FALSE(list2.Queued(&nodes[2]));
104 
105   EXPECT_EQ(list1.Next(&nodes[1]), &nodes[0]);
106   EXPECT_EQ(list1.Prev(&nodes[1]), &nodes[2]);
107 
108   EXPECT_EQ(list2.Next(&nodes[1]), nullptr);
109   EXPECT_EQ(list2.Prev(&nodes[1]), nullptr);
110 
111   list1.Remove(&nodes[1]);
112   EXPECT_EQ(list1.Size(), (size_t)2);
113   EXPECT_FALSE(list1.Queued(&nodes[1]));
114   EXPECT_EQ(list2.Size(), (size_t)1);
115   EXPECT_TRUE(list2.Queued(&nodes[1]));
116 
117   EXPECT_EQ(list1.PopBack(), &nodes[0]);
118   EXPECT_EQ(list1.PopBack(), &nodes[2]);
119   EXPECT_EQ(list1.Size(), (size_t)0);
120 
121   EXPECT_EQ(list2.PopBack(), &nodes[1]);
122   EXPECT_EQ(list2.Size(), (size_t)0);
123 }
124 
125 }  // namespace __tsan
126