70 lines · cpp
1// RUN: %clangxx -pthread %s -o %t2// RUN: %env_tool_opts=detect_invalid_join=false %run %t 03 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: glibc8 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(1);20 auto ret = (void *)(~(uintptr_t)args);21 if (use_exit)22 pthread_exit(ret);23 return ret;24}25 26int 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