1 //===-- sanitizer_list_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/AddressSanitizer runtime.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "sanitizer_common/sanitizer_list.h"
14 #include "gtest/gtest.h"
15
16 namespace __sanitizer {
17
18 struct ListItem {
19 ListItem *next;
20 };
21
22 typedef IntrusiveList<ListItem> List;
23
24 // Check that IntrusiveList can be made thread-local.
25 static THREADLOCAL List static_list;
26
SetList(List * l,ListItem * x=0,ListItem * y=0,ListItem * z=0)27 static void SetList(List *l, ListItem *x = 0,
28 ListItem *y = 0, ListItem *z = 0) {
29 l->clear();
30 if (x) l->push_back(x);
31 if (y) l->push_back(y);
32 if (z) l->push_back(z);
33 }
34
CheckList(List * l,ListItem * i1,ListItem * i2=0,ListItem * i3=0,ListItem * i4=0,ListItem * i5=0,ListItem * i6=0)35 static void CheckList(List *l, ListItem *i1, ListItem *i2 = 0, ListItem *i3 = 0,
36 ListItem *i4 = 0, ListItem *i5 = 0, ListItem *i6 = 0) {
37 if (i1) {
38 CHECK_EQ(l->front(), i1);
39 l->pop_front();
40 }
41 if (i2) {
42 CHECK_EQ(l->front(), i2);
43 l->pop_front();
44 }
45 if (i3) {
46 CHECK_EQ(l->front(), i3);
47 l->pop_front();
48 }
49 if (i4) {
50 CHECK_EQ(l->front(), i4);
51 l->pop_front();
52 }
53 if (i5) {
54 CHECK_EQ(l->front(), i5);
55 l->pop_front();
56 }
57 if (i6) {
58 CHECK_EQ(l->front(), i6);
59 l->pop_front();
60 }
61 CHECK(l->empty());
62 }
63
TEST(SanitizerCommon,IntrusiveList)64 TEST(SanitizerCommon, IntrusiveList) {
65 ListItem items[6];
66 CHECK_EQ(static_list.size(), 0);
67
68 List l;
69 l.clear();
70
71 ListItem *x = &items[0];
72 ListItem *y = &items[1];
73 ListItem *z = &items[2];
74 ListItem *a = &items[3];
75 ListItem *b = &items[4];
76 ListItem *c = &items[5];
77
78 CHECK_EQ(l.size(), 0);
79 l.push_back(x);
80 CHECK_EQ(l.size(), 1);
81 CHECK_EQ(l.back(), x);
82 CHECK_EQ(l.front(), x);
83 l.pop_front();
84 CHECK(l.empty());
85 l.CheckConsistency();
86
87 l.push_front(x);
88 CHECK_EQ(l.size(), 1);
89 CHECK_EQ(l.back(), x);
90 CHECK_EQ(l.front(), x);
91 l.pop_front();
92 CHECK(l.empty());
93 l.CheckConsistency();
94
95 l.push_front(x);
96 l.push_front(y);
97 l.push_front(z);
98 CHECK_EQ(l.size(), 3);
99 CHECK_EQ(l.front(), z);
100 CHECK_EQ(l.back(), x);
101 l.CheckConsistency();
102
103 l.pop_front();
104 CHECK_EQ(l.size(), 2);
105 CHECK_EQ(l.front(), y);
106 CHECK_EQ(l.back(), x);
107 l.pop_front();
108 l.pop_front();
109 CHECK(l.empty());
110 l.CheckConsistency();
111
112 l.push_back(x);
113 l.push_back(y);
114 l.push_back(z);
115 CHECK_EQ(l.size(), 3);
116 CHECK_EQ(l.front(), x);
117 CHECK_EQ(l.back(), z);
118 l.CheckConsistency();
119
120 l.pop_front();
121 CHECK_EQ(l.size(), 2);
122 CHECK_EQ(l.front(), y);
123 CHECK_EQ(l.back(), z);
124 l.pop_front();
125 l.pop_front();
126 CHECK(l.empty());
127 l.CheckConsistency();
128
129 List l1, l2;
130 l1.clear();
131 l2.clear();
132
133 l1.append_front(&l2);
134 CHECK(l1.empty());
135 CHECK(l2.empty());
136
137 l1.append_back(&l2);
138 CHECK(l1.empty());
139 CHECK(l2.empty());
140
141 SetList(&l1, x);
142 CheckList(&l1, x);
143
144 SetList(&l1, x, y, z);
145 SetList(&l2, a, b, c);
146 l1.append_back(&l2);
147 CheckList(&l1, x, y, z, a, b, c);
148 CHECK(l2.empty());
149
150 SetList(&l1, x, y);
151 SetList(&l2);
152 l1.append_front(&l2);
153 CheckList(&l1, x, y);
154 CHECK(l2.empty());
155 }
156
157 } // namespace __sanitizer
158