1e99207feSJoachim Protze // RUN: %libarcher-compile -fopenmp-version=50 && env OMP_NUM_THREADS='3' \
2e99207feSJoachim Protze // RUN: %libarcher-run-race | FileCheck %s
3e99207feSJoachim Protze
4*c46ccb85SJoachim Protze // Checked gcc 10.1 still does not support detach clause on task construct.
5*c46ccb85SJoachim Protze // UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-8, gcc-9, gcc-10
6*c46ccb85SJoachim Protze // gcc 11 introduced detach clause, but gomp interface in libomp has no support
7*c46ccb85SJoachim Protze // XFAIL: gcc-11, gcc-12
8e99207feSJoachim Protze // clang supports detach clause since version 11.
9e99207feSJoachim Protze // UNSUPPORTED: clang-10, clang-9, clang-8, clang-7
10e99207feSJoachim Protze // icc compiler does not support detach clause.
11e99207feSJoachim Protze // UNSUPPORTED: icc
12e99207feSJoachim Protze // REQUIRES: tsan
13e99207feSJoachim Protze
14e99207feSJoachim Protze #include <omp.h>
15e99207feSJoachim Protze #include <stdio.h>
16e99207feSJoachim Protze #include <unistd.h>
17e99207feSJoachim Protze
main()18e99207feSJoachim Protze int main() {
19e99207feSJoachim Protze #pragma omp parallel
20e99207feSJoachim Protze #pragma omp master
21e99207feSJoachim Protze {
22e99207feSJoachim Protze omp_event_handle_t event;
23e99207feSJoachim Protze int a = 0, b = 0;
24e99207feSJoachim Protze omp_event_handle_t *f_event;
25e99207feSJoachim Protze #pragma omp task detach(event) depend(out : f_event) shared(f_event)
26e99207feSJoachim Protze {
27e99207feSJoachim Protze printf("%i: task 1\n", omp_get_thread_num());
28e99207feSJoachim Protze f_event = &event;
29e99207feSJoachim Protze }
30e99207feSJoachim Protze usleep(10000);
31e99207feSJoachim Protze #pragma omp task depend(in : f_event) shared(f_event, a, b)
32e99207feSJoachim Protze {
33e99207feSJoachim Protze printf("%i: task 2, %p, %i, %i\n", omp_get_thread_num(), f_event, a, b);
34e99207feSJoachim Protze f_event = &event;
35e99207feSJoachim Protze }
36e99207feSJoachim Protze usleep(10000);
37e99207feSJoachim Protze a++;
38e99207feSJoachim Protze printf("%i: calling omp_fulfill_event\n", omp_get_thread_num());
393fa2e193SJoachim Protze omp_fulfill_event(event);
40e99207feSJoachim Protze //#pragma omp task if (0) depend(in : f_event)
41e99207feSJoachim Protze // {}
42e99207feSJoachim Protze b++;
43e99207feSJoachim Protze usleep(10000);
44e99207feSJoachim Protze #pragma omp taskwait
45e99207feSJoachim Protze }
46e99207feSJoachim Protze return 0;
47e99207feSJoachim Protze }
48e99207feSJoachim Protze
49e99207feSJoachim Protze // no race for a++ in line 32:
50*c46ccb85SJoachim Protze // CHECK-NOT: #0 {{.*}}task_late_fulfill.c:37
51e99207feSJoachim Protze
52e99207feSJoachim Protze // CHECK: WARNING: ThreadSanitizer: data race
53e99207feSJoachim Protze // CHECK-NEXT: {{(Write|Read)}} of size 4
54*c46ccb85SJoachim Protze // CHECK-NEXT: #0 {{.*}}task_late_fulfill.c:33
55e99207feSJoachim Protze // CHECK: Previous write of size 4
56*c46ccb85SJoachim Protze // CHECK-NEXT: #0 {{.*}}task_late_fulfill.c:42
57