xref: /llvm-project/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp (revision 5e406615fea185656786e8a5e72b6f12fd7706d5)
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 
17 bool use_exit;
fn(void * args)18 static void *fn(void *args) {
19   sleep(1);
20   auto ret = (void *)(~(uintptr_t)args);
21   if (use_exit)
22     pthread_exit(ret);
23   return ret;
24 }
25 
main(int argc,char ** argv)26 int main(int argc, char **argv) {
27   use_exit = atoi(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(thread[1], &res))
45       sleep(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 = {0, 1};
54     while (pthread_timedjoin_np(thread[2], &res, &tm))
55       sleep(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