1// RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=atexit_sleep_ms=50 %run %t 2>&1 | FileCheck %s
2#include "../test.h"
3#include <errno.h>
4#include <sanitizer/linux_syscall_hooks.h>
5#include <sys/syscall.h>
6#include <sys/types.h>
7#include <sys/wait.h>
8
9int counter;
10
11static void *incrementer(void *p) {
12 for (;;)
13 __sync_fetch_and_add(&counter, 1);
14 return 0;
15}
16
17int myfork() {
18 __sanitizer_syscall_pre_fork();
19#ifdef SYS_fork
20 int res = syscall(SYS_fork);
21#else
22 int res = syscall(SYS_clone, SIGCHLD, 0);
23#endif
24 __sanitizer_syscall_post_fork(res);
25 return res;
26}
27
28int main() {
29 barrier_init(&barrier, 2);
30 pthread_t th1;
31 pthread_create(&th1, 0, incrementer, 0);
32 for (int i = 0; i < 10; i++) {
33 switch (myfork()) {
34 default: // parent
35 while (wait(0) < 0) {
36 }
37 fprintf(stderr, ".");
38 break;
39 case 0: // child
40 __sync_fetch_and_add(&counter, 1);
41 exit(0);
42 break;
43 case -1: // error
44 fprintf(stderr, "failed to fork (%d)\n", errno);
45 exit(1);
46 }
47 }
48 fprintf(stderr, "OK\n");
49}
50
51// CHECK: OK
52