1 //===-- sanitizer_thread_registry_test.cpp --------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file is a part of shared sanitizer runtime.
11 //===----------------------------------------------------------------------===//
12 #include "sanitizer_common/sanitizer_thread_arg_retval.h"
14 #include "gtest/gtest.h"
15 #include "sanitizer_mutex.h"
17 namespace __sanitizer
{
20 static void* arg
= &t
;
21 static void* (*routine
)(void*) = [](void*) { return arg
; };
22 static void* retval
= (&t
) + 1;
24 TEST(ThreadArgRetvalTest
, CreateFail
) {
26 td
.Create(false, {routine
, arg
}, []() { return 0; });
27 EXPECT_EQ(0u, td
.size());
30 TEST(ThreadArgRetvalTest
, CreateRunJoin
) {
32 td
.Create(false, {routine
, arg
}, []() { return 1; });
33 EXPECT_EQ(1u, td
.size());
35 EXPECT_EQ(arg
, td
.GetArgs(1).arg_retval
);
36 EXPECT_EQ(routine
, td
.GetArgs(1).routine
);
37 EXPECT_EQ(1u, td
.size());
40 EXPECT_EQ(1u, td
.size());
42 td
.Join(1, []() { return false; });
43 EXPECT_EQ(1u, td
.size());
45 td
.Join(1, []() { return true; });
46 EXPECT_EQ(0u, td
.size());
49 TEST(ThreadArgRetvalTest
, CreateJoinRun
) {
51 td
.Create(false, {routine
, arg
}, []() { return 1; });
52 EXPECT_EQ(1u, td
.size());
54 td
.Join(1, []() { return false; });
55 EXPECT_EQ(1u, td
.size());
58 // Expected to happen on another thread.
59 EXPECT_EQ(1u, td
.size());
61 EXPECT_EQ(arg
, td
.GetArgs(1).arg_retval
);
62 EXPECT_EQ(routine
, td
.GetArgs(1).routine
);
63 EXPECT_EQ(1u, td
.size());
66 EXPECT_EQ(1u, td
.size());
69 EXPECT_EQ(0u, td
.size());
72 TEST(ThreadArgRetvalTest
, CreateRunDetach
) {
74 td
.Create(false, {routine
, arg
}, []() { return 1; });
75 EXPECT_EQ(1u, td
.size());
77 EXPECT_EQ(arg
, td
.GetArgs(1).arg_retval
);
78 EXPECT_EQ(routine
, td
.GetArgs(1).routine
);
79 EXPECT_EQ(1u, td
.size());
82 EXPECT_EQ(1u, td
.size());
84 td
.Detach(1, []() { return false; });
85 EXPECT_EQ(1u, td
.size());
87 td
.Detach(1, []() { return true; });
88 EXPECT_EQ(0u, td
.size());
91 TEST(ThreadArgRetvalTest
, CreateDetachRun
) {
93 td
.Create(false, {routine
, arg
}, []() { return 1; });
94 EXPECT_EQ(1u, td
.size());
96 td
.Detach(1, []() { return true; });
97 EXPECT_EQ(1u, td
.size());
99 EXPECT_EQ(arg
, td
.GetArgs(1).arg_retval
);
100 EXPECT_EQ(routine
, td
.GetArgs(1).routine
);
101 EXPECT_EQ(1u, td
.size());
103 td
.Finish(1, retval
);
104 EXPECT_EQ(0u, td
.size());
107 TEST(ThreadArgRetvalTest
, CreateRunJoinReuse
) {
109 td
.Create(false, {routine
, arg
}, []() { return 1; });
110 EXPECT_EQ(1u, td
.size());
112 td
.Finish(1, retval
);
113 EXPECT_EQ(1u, td
.size());
117 td
.Create(false, {routine
, arg
}, []() { return 1; });
118 EXPECT_EQ(1u, td
.size());
121 // Even if JoinFn succeeded, we can't erase mismatching thread.
122 EXPECT_EQ(1u, td
.size());
124 // Now we can join another one.
125 td
.Join(1, []() { return true; });
126 EXPECT_EQ(0u, td
.size());
129 TEST(ThreadArgRetvalTest
, GetAllPtrsLocked
) {
131 td
.Create(false, {routine
, arg
}, []() { return 1; });
133 GenericScopedLock
<ThreadArgRetval
> lock(&td
);
134 InternalMmapVector
<uptr
> ptrs
;
135 td
.GetAllPtrsLocked(&ptrs
);
136 EXPECT_EQ(1u, ptrs
.size());
137 EXPECT_EQ((uptr
)arg
, ptrs
[0]);
140 td
.Finish(1, retval
);
142 GenericScopedLock
<ThreadArgRetval
> lock(&td
);
143 InternalMmapVector
<uptr
> ptrs
;
144 td
.GetAllPtrsLocked(&ptrs
);
145 EXPECT_EQ(1u, ptrs
.size());
146 EXPECT_EQ((uptr
)retval
, ptrs
[0]);
149 td
.Join(1, []() { return true; });
151 GenericScopedLock
<ThreadArgRetval
> lock(&td
);
152 InternalMmapVector
<uptr
> ptrs
;
153 td
.GetAllPtrsLocked(&ptrs
);
154 EXPECT_TRUE(ptrs
.empty());
158 } // namespace __sanitizer