1// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2#include "test.h"
3#include <errno.h>
4#include <sys/mman.h>
5
6void *SubWorker(void *arg) {
7 (void)arg;
8 const int kMmapSize = 65536;
9 for (int i = 0; i < 500; i++) {
10 int *ptr = (int*)mmap(0, kMmapSize, PROT_READ | PROT_WRITE,
11 MAP_PRIVATE | MAP_ANON, -1, 0);
12 if (ptr == MAP_FAILED)
13 exit(printf("mmap failed: %d\n", errno));
14 *ptr = 42;
15 if (munmap(ptr, kMmapSize))
16 exit(printf("munmap failed: %d\n", errno));
17 }
18 return 0;
19}
20
21void *Worker1(void *arg) {
22 (void)arg;
23 pthread_t th[4];
24 for (int i = 0; i < 4; i++) {
25 if (pthread_create(&th[i], 0, SubWorker, 0))
26 exit(printf("pthread_create failed: %d\n", errno));
27 }
28 for (int i = 0; i < 4; i++) {
29 if (pthread_join(th[i], 0))
30 exit(printf("pthread_join failed: %d\n", errno));
31 }
32 return 0;
33}
34
35void *Worker(void *arg) {
36 (void)arg;
37 pthread_t th[4];
38 for (int i = 0; i < 4; i++) {
39 if (pthread_create(&th[i], 0, Worker1, 0))
40 exit(printf("pthread_create failed: %d\n", errno));
41 }
42 for (int i = 0; i < 4; i++) {
43 if (pthread_join(th[i], 0))
44 exit(printf("pthread_join failed: %d\n", errno));
45 }
46 return 0;
47}
48
49int main() {
50 // This test is flaky on several builders:
51 // https://groups.google.com/d/msg/llvm-dev/KUFPdLhBN3Q/L75rwW9xBgAJ
52 // The cause is unknown (lit hides test output on failures).
53#if 0
54 pthread_t th[4];
55 for (int i = 0; i < 4; i++) {
56 if (pthread_create(&th[i], 0, Worker, 0))
57 exit(printf("pthread_create failed: %d\n", errno));
58 }
59 for (int i = 0; i < 4; i++) {
60 if (pthread_join(th[i], 0))
61 exit(printf("pthread_join failed: %d\n", errno));
62 }
63#endif
64 fprintf(stderr, "DONE\n");
65}
66
67// CHECK: DONE
68