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