1 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2 #include <pthread.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 
8 int fds[2];
9 int X;
10 
Thread1(void * x)11 void *Thread1(void *x) {
12   X = 42;
13   write(fds[1], "a", 1);
14   return NULL;
15 }
16 
Thread2(void * x)17 void *Thread2(void *x) {
18   char buf;
19   while (read(fds[0], &buf, 1) != 1) {
20   }
21   X = 43;
22   return NULL;
23 }
24 
main()25 int main() {
26   pipe(fds);
27   int pid = vfork();
28   if (pid < 0) {
29     fprintf(stderr, "FAIL to vfork\n");
30     exit(1);
31   }
32   if (pid == 0) {  // child
33     // Closing of fds must not affect parent process.
34     // Strictly saying this is undefined behavior, because vfork child is not
35     // allowed to call any functions other than exec/exit. But this is what
36     // openjdk does.
37     close(fds[0]);
38     close(fds[1]);
39     _exit(0);
40   }
41   pthread_t t[2];
42   pthread_create(&t[0], NULL, Thread1, NULL);
43   pthread_create(&t[1], NULL, Thread2, NULL);
44   pthread_join(t[0], NULL);
45   pthread_join(t[1], NULL);
46   fprintf(stderr, "DONE\n");
47 }
48 
49 // CHECK-NOT: WARNING: ThreadSanitizer: data race
50 // CHECK-NOT: FAIL to vfork
51 // CHECK: DONE
52