Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / lib / sanitizer_common / tests / sanitizer_thread_arg_retval_test.cpp
blob31507c8df19cf6122260002ed07c7dccf178b0be
1 //===-- sanitizer_thread_registry_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 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 {
19 static int t;
20 static void* arg = &t;
21 static void* (*routine)(void*) = [](void*) { return arg; };
22 static void* retval = (&t) + 1;
24 TEST(ThreadArgRetvalTest, CreateFail) {
25 ThreadArgRetval td;
26 td.Create(false, {routine, arg}, []() { return 0; });
27 EXPECT_EQ(0u, td.size());
30 TEST(ThreadArgRetvalTest, CreateRunJoin) {
31 ThreadArgRetval td;
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());
39 td.Finish(1, retval);
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) {
50 ThreadArgRetval td;
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());
57 td.Join(1, [&]() {
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());
65 td.Finish(1, retval);
66 EXPECT_EQ(1u, td.size());
67 return true;
68 });
69 EXPECT_EQ(0u, td.size());
72 TEST(ThreadArgRetvalTest, CreateRunDetach) {
73 ThreadArgRetval td;
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());
81 td.Finish(1, retval);
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) {
92 ThreadArgRetval td;
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) {
108 ThreadArgRetval td;
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());
115 td.Join(1, [&]() {
116 // Reuse thread id.
117 td.Create(false, {routine, arg}, []() { return 1; });
118 EXPECT_EQ(1u, td.size());
119 return true;
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) {
130 ThreadArgRetval td;
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