1ed7bf7d7SDmitry Vyukov // RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=atexit_sleep_ms=50 %run %t 2>&1 | FileCheck %s
2ed7bf7d7SDmitry Vyukov #include "../test.h"
3*04b2ada5SDmitry Vyukov #include "syscall.h"
4ed7bf7d7SDmitry Vyukov #include <errno.h>
5ed7bf7d7SDmitry Vyukov #include <sys/types.h>
6ed7bf7d7SDmitry Vyukov #include <sys/wait.h>
7ed7bf7d7SDmitry Vyukov 
8ed7bf7d7SDmitry Vyukov int counter;
9ed7bf7d7SDmitry Vyukov 
incrementer(void * p)10ed7bf7d7SDmitry Vyukov static void *incrementer(void *p) {
11ed7bf7d7SDmitry Vyukov   for (;;)
12ed7bf7d7SDmitry Vyukov     __sync_fetch_and_add(&counter, 1);
13ed7bf7d7SDmitry Vyukov   return 0;
14ed7bf7d7SDmitry Vyukov }
15ed7bf7d7SDmitry Vyukov 
main()16ed7bf7d7SDmitry Vyukov int main() {
17ed7bf7d7SDmitry Vyukov   pthread_t th1;
18ed7bf7d7SDmitry Vyukov   pthread_create(&th1, 0, incrementer, 0);
19ed7bf7d7SDmitry Vyukov   for (int i = 0; i < 10; i++) {
20ed7bf7d7SDmitry Vyukov     switch (myfork()) {
21ed7bf7d7SDmitry Vyukov     default: // parent
22ed7bf7d7SDmitry Vyukov       while (wait(0) < 0) {
23ed7bf7d7SDmitry Vyukov       }
24ed7bf7d7SDmitry Vyukov       fprintf(stderr, ".");
25ed7bf7d7SDmitry Vyukov       break;
26ed7bf7d7SDmitry Vyukov     case 0: // child
27ed7bf7d7SDmitry Vyukov       __sync_fetch_and_add(&counter, 1);
28ed7bf7d7SDmitry Vyukov       exit(0);
29ed7bf7d7SDmitry Vyukov       break;
30ed7bf7d7SDmitry Vyukov     case -1: // error
31ed7bf7d7SDmitry Vyukov       fprintf(stderr, "failed to fork (%d)\n", errno);
32ed7bf7d7SDmitry Vyukov       exit(1);
33ed7bf7d7SDmitry Vyukov     }
34ed7bf7d7SDmitry Vyukov   }
35ed7bf7d7SDmitry Vyukov   fprintf(stderr, "OK\n");
36ed7bf7d7SDmitry Vyukov }
37ed7bf7d7SDmitry Vyukov 
38ed7bf7d7SDmitry Vyukov // CHECK: OK
39