159 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of shared sanitizer runtime.10//11//===----------------------------------------------------------------------===//12#include "sanitizer_common/sanitizer_thread_arg_retval.h"13 14#include "gtest/gtest.h"15#include "sanitizer_mutex.h"16 17namespace __sanitizer {18 19static int t;20static void* arg = &t;21static void* (*routine)(void*) = [](void*) { return arg; };22static void* retval = (&t) + 1;23 24TEST(ThreadArgRetvalTest, CreateFail) {25 ThreadArgRetval td;26 td.Create(false, {routine, arg}, []() { return 0; });27 EXPECT_EQ(0u, td.size());28}29 30TEST(ThreadArgRetvalTest, CreateRunJoin) {31 ThreadArgRetval td;32 td.Create(false, {routine, arg}, []() { return 1; });33 EXPECT_EQ(1u, td.size());34 35 EXPECT_EQ(arg, td.GetArgs(1).arg_retval);36 EXPECT_EQ(routine, td.GetArgs(1).routine);37 EXPECT_EQ(1u, td.size());38 39 td.Finish(1, retval);40 EXPECT_EQ(1u, td.size());41 42 td.Join(1, []() { return false; });43 EXPECT_EQ(1u, td.size());44 45 td.Join(1, []() { return true; });46 EXPECT_EQ(0u, td.size());47}48 49TEST(ThreadArgRetvalTest, CreateJoinRun) {50 ThreadArgRetval td;51 td.Create(false, {routine, arg}, []() { return 1; });52 EXPECT_EQ(1u, td.size());53 54 td.Join(1, []() { return false; });55 EXPECT_EQ(1u, td.size());56 57 td.Join(1, [&]() {58 // Expected to happen on another thread.59 EXPECT_EQ(1u, td.size());60 61 EXPECT_EQ(arg, td.GetArgs(1).arg_retval);62 EXPECT_EQ(routine, td.GetArgs(1).routine);63 EXPECT_EQ(1u, td.size());64 65 td.Finish(1, retval);66 EXPECT_EQ(1u, td.size());67 return true;68 });69 EXPECT_EQ(0u, td.size());70}71 72TEST(ThreadArgRetvalTest, CreateRunDetach) {73 ThreadArgRetval td;74 td.Create(false, {routine, arg}, []() { return 1; });75 EXPECT_EQ(1u, td.size());76 77 EXPECT_EQ(arg, td.GetArgs(1).arg_retval);78 EXPECT_EQ(routine, td.GetArgs(1).routine);79 EXPECT_EQ(1u, td.size());80 81 td.Finish(1, retval);82 EXPECT_EQ(1u, td.size());83 84 td.Detach(1, []() { return false; });85 EXPECT_EQ(1u, td.size());86 87 td.Detach(1, []() { return true; });88 EXPECT_EQ(0u, td.size());89}90 91TEST(ThreadArgRetvalTest, CreateDetachRun) {92 ThreadArgRetval td;93 td.Create(false, {routine, arg}, []() { return 1; });94 EXPECT_EQ(1u, td.size());95 96 td.Detach(1, []() { return true; });97 EXPECT_EQ(1u, td.size());98 99 EXPECT_EQ(arg, td.GetArgs(1).arg_retval);100 EXPECT_EQ(routine, td.GetArgs(1).routine);101 EXPECT_EQ(1u, td.size());102 103 td.Finish(1, retval);104 EXPECT_EQ(0u, td.size());105}106 107TEST(ThreadArgRetvalTest, CreateRunJoinReuse) {108 ThreadArgRetval td;109 td.Create(false, {routine, arg}, []() { return 1; });110 EXPECT_EQ(1u, td.size());111 112 td.Finish(1, retval);113 EXPECT_EQ(1u, td.size());114 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;120 });121 // Even if JoinFn succeeded, we can't erase mismatching thread.122 EXPECT_EQ(1u, td.size());123 124 // Now we can join another one.125 td.Join(1, []() { return true; });126 EXPECT_EQ(0u, td.size());127}128 129TEST(ThreadArgRetvalTest, GetAllPtrsLocked) {130 ThreadArgRetval td;131 td.Create(false, {routine, arg}, []() { return 1; });132 {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]);138 }139 140 td.Finish(1, retval);141 {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]);147 }148 149 td.Join(1, []() { return true; });150 {151 GenericScopedLock<ThreadArgRetval> lock(&td);152 InternalMmapVector<uptr> ptrs;153 td.GetAllPtrsLocked(&ptrs);154 EXPECT_TRUE(ptrs.empty());155 }156}157 158} // namespace __sanitizer159