1// RUN: %clangxx -pthread %s -o %t
2// RUN: %env_tool_opts=detect_invalid_join=false %run %t 0
3
4// FIXME: Crashes on some bots in pthread_exit.
5// RUN: %env_tool_opts=detect_invalid_join=false %run %t %if tsan %{ 0 %} %else %{ 1 %}
6
7// REQUIRES: glibc
8
9#include <assert.h>
10#include <ctime>
11#include <errno.h>
12#include <pthread.h>
13#include <stdint.h>
14#include <stdlib.h>
15#include <unistd.h>
16
17bool use_exit;
18static void *fn(void *args) {
19 sleep(seconds: 1);
20 auto ret = (void *)(~(uintptr_t)args);
21 if (use_exit)
22 pthread_exit(retval: ret);
23 return ret;
24}
25
26int main(int argc, char **argv) {
27 use_exit = atoi(nptr: argv[1]);
28 bool check_invalid_join = !use_exit;
29 pthread_t thread[5];
30 assert(!pthread_create(&thread[0], nullptr, fn, (void *)1000));
31 assert(!pthread_create(&thread[1], nullptr, fn, (void *)1001));
32 assert(!pthread_create(&thread[2], nullptr, fn, (void *)1002));
33 assert(!pthread_create(&thread[3], nullptr, fn, (void *)1003));
34 pthread_attr_t attr;
35 assert(!pthread_attr_init(&attr));
36 assert(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
37 assert(!pthread_create(&thread[4], &attr, fn, (void *)1004));
38 assert(!pthread_attr_destroy(&attr));
39
40 assert(!pthread_detach(thread[0]));
41
42 {
43 void *res;
44 while (pthread_tryjoin_np(th: thread[1], thread_return: &res))
45 sleep(seconds: 1);
46 assert(~(uintptr_t)res == 1001);
47 assert(check_invalid_join ||
48 (pthread_tryjoin_np(thread[1], &res) == EBUSY));
49 }
50
51 {
52 void *res;
53 timespec tm = {.tv_sec: 0, .tv_nsec: 1};
54 while (pthread_timedjoin_np(th: thread[2], thread_return: &res, abstime: &tm))
55 sleep(seconds: 1);
56 assert(~(uintptr_t)res == 1002);
57 assert(check_invalid_join ||
58 (pthread_timedjoin_np(thread[2], &res, &tm) == ESRCH));
59 }
60
61 {
62 void *res;
63 assert(!pthread_join(thread[3], &res));
64 assert(~(uintptr_t)res == 1003);
65 assert(check_invalid_join || (pthread_join(thread[3], &res) == ESRCH));
66 }
67
68 return 0;
69}
70

source code of compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp