Mercurial > hg > CbC > CbC_llvm
comparison compiler-rt/test/tsan/java_finalizer2.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
1 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s | |
2 // Regression test for https://github.com/golang/go/issues/39186 | |
3 | |
4 // pthread barriers are not available on OS X | |
5 // UNSUPPORTED: darwin | |
6 | |
7 #include "java.h" | |
8 #include <string.h> | |
9 | |
10 struct Heap { | |
11 uint64_t data; | |
12 uint64_t ready; | |
13 uint64_t finalized; | |
14 uint64_t wg; | |
15 pthread_barrier_t barrier_finalizer; | |
16 pthread_barrier_t barrier_ballast; | |
17 }; | |
18 | |
19 void *Thread1(void *p) { | |
20 Heap* heap = (Heap*)p; | |
21 pthread_barrier_wait(&heap->barrier_finalizer); | |
22 __tsan_java_finalize(); | |
23 __atomic_fetch_add(&heap->wg, 1, __ATOMIC_RELEASE); | |
24 __atomic_store_n(&heap->finalized, 1, __ATOMIC_RELAXED); | |
25 return 0; | |
26 } | |
27 | |
28 void *Thread2(void *p) { | |
29 Heap* heap = (Heap*)p; | |
30 pthread_barrier_wait(&heap->barrier_finalizer); | |
31 heap->data = 1; | |
32 __atomic_store_n(&heap->ready, 1, __ATOMIC_RELEASE); | |
33 return 0; | |
34 } | |
35 | |
36 void *Thread3(void *p) { | |
37 Heap* heap = (Heap*)p; | |
38 pthread_barrier_wait(&heap->barrier_finalizer); | |
39 while (__atomic_load_n(&heap->ready, __ATOMIC_ACQUIRE) != 1) | |
40 pthread_yield(); | |
41 while (__atomic_load_n(&heap->finalized, __ATOMIC_RELAXED) != 1) | |
42 pthread_yield(); | |
43 __atomic_fetch_add(&heap->wg, 1, __ATOMIC_RELEASE); | |
44 return 0; | |
45 } | |
46 | |
47 void *Ballast(void *p) { | |
48 Heap* heap = (Heap*)p; | |
49 pthread_barrier_wait(&heap->barrier_ballast); | |
50 return 0; | |
51 } | |
52 | |
53 int main() { | |
54 Heap* heap = (Heap*)calloc(sizeof(Heap), 2) + 1; | |
55 __tsan_java_init((jptr)heap, sizeof(*heap)); | |
56 __tsan_java_alloc((jptr)heap, sizeof(*heap)); | |
57 // Ballast threads merely make the bug a bit easier to trigger. | |
58 const int kBallastThreads = 100; | |
59 pthread_barrier_init(&heap->barrier_finalizer, 0, 4); | |
60 pthread_barrier_init(&heap->barrier_ballast, 0, kBallastThreads + 1); | |
61 pthread_t th[3]; | |
62 pthread_create(&th[0], 0, Thread1, heap); | |
63 pthread_create(&th[1], 0, Thread2, heap); | |
64 pthread_t ballast[kBallastThreads]; | |
65 for (int i = 0; i < kBallastThreads; i++) | |
66 pthread_create(&ballast[i], 0, Ballast, heap); | |
67 pthread_create(&th[2], 0, Thread3, heap); | |
68 pthread_barrier_wait(&heap->barrier_ballast); | |
69 for (int i = 0; i < kBallastThreads; i++) | |
70 pthread_join(ballast[i], 0); | |
71 pthread_barrier_wait(&heap->barrier_finalizer); | |
72 while (__atomic_load_n(&heap->wg, __ATOMIC_ACQUIRE) != 2) | |
73 pthread_yield(); | |
74 if (heap->data != 1) | |
75 exit(printf("no data\n")); | |
76 for (int i = 0; i < 3; i++) | |
77 pthread_join(th[i], 0); | |
78 pthread_barrier_destroy(&heap->barrier_ballast); | |
79 pthread_barrier_destroy(&heap->barrier_finalizer); | |
80 __tsan_java_free((jptr)heap, sizeof(*heap)); | |
81 fprintf(stderr, "DONE\n"); | |
82 return __tsan_java_fini(); | |
83 } | |
84 | |
85 // CHECK-NOT: WARNING: ThreadSanitizer: data race | |
86 // CHECK: DONE |