1*72ada5aeSPeyton, Jonathan L // RUN: %libomp-compile-and-run
2*72ada5aeSPeyton, Jonathan L // UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-8
3*72ada5aeSPeyton, Jonathan L // UNSUPPORTED: clang-3, clang-4, clang-5, clang-6, clang-7, clang-8
4*72ada5aeSPeyton, Jonathan L // TODO: update expected result when icc supports mutexinoutset
5*72ada5aeSPeyton, Jonathan L // XFAIL: icc
6*72ada5aeSPeyton, Jonathan L
7*72ada5aeSPeyton, Jonathan L // Tests OMP 5.0 task dependences "mutexinoutset", emulates compiler codegen
8*72ada5aeSPeyton, Jonathan L // Mutually exclusive tasks get same input dependency info array
9*72ada5aeSPeyton, Jonathan L //
10*72ada5aeSPeyton, Jonathan L // Task tree created:
11*72ada5aeSPeyton, Jonathan L // task0 task1
12*72ada5aeSPeyton, Jonathan L // \ / \
13*72ada5aeSPeyton, Jonathan L // task2 task5
14*72ada5aeSPeyton, Jonathan L // / \
15*72ada5aeSPeyton, Jonathan L // task3 task4
16*72ada5aeSPeyton, Jonathan L // / \
17*72ada5aeSPeyton, Jonathan L // task6 <-->task7 (these two are mutually exclusive)
18*72ada5aeSPeyton, Jonathan L // \ /
19*72ada5aeSPeyton, Jonathan L // task8
20*72ada5aeSPeyton, Jonathan L //
21*72ada5aeSPeyton, Jonathan L #include <stdio.h>
22*72ada5aeSPeyton, Jonathan L #include <omp.h>
23*72ada5aeSPeyton, Jonathan L #include "omp_my_sleep.h"
24*72ada5aeSPeyton, Jonathan L
25*72ada5aeSPeyton, Jonathan L static int checker = 0; // to check if two tasks run simultaneously
26*72ada5aeSPeyton, Jonathan L static int err = 0;
27*72ada5aeSPeyton, Jonathan L #ifndef DELAY
28*72ada5aeSPeyton, Jonathan L #define DELAY 0.1
29*72ada5aeSPeyton, Jonathan L #endif
30*72ada5aeSPeyton, Jonathan L
mutex_task(int task_id)31*72ada5aeSPeyton, Jonathan L int mutex_task(int task_id) {
32*72ada5aeSPeyton, Jonathan L int th = omp_get_thread_num();
33*72ada5aeSPeyton, Jonathan L #pragma omp atomic
34*72ada5aeSPeyton, Jonathan L ++checker;
35*72ada5aeSPeyton, Jonathan L printf("task %d, th %d\n", task_id, th);
36*72ada5aeSPeyton, Jonathan L if (checker != 1) {
37*72ada5aeSPeyton, Jonathan L err++;
38*72ada5aeSPeyton, Jonathan L printf("Error1, checker %d != 1\n", checker);
39*72ada5aeSPeyton, Jonathan L }
40*72ada5aeSPeyton, Jonathan L my_sleep(DELAY);
41*72ada5aeSPeyton, Jonathan L if (checker != 1) {
42*72ada5aeSPeyton, Jonathan L err++;
43*72ada5aeSPeyton, Jonathan L printf("Error2, checker %d != 1\n", checker);
44*72ada5aeSPeyton, Jonathan L }
45*72ada5aeSPeyton, Jonathan L #pragma omp atomic
46*72ada5aeSPeyton, Jonathan L --checker;
47*72ada5aeSPeyton, Jonathan L return 0;
48*72ada5aeSPeyton, Jonathan L }
49*72ada5aeSPeyton, Jonathan L
main()50*72ada5aeSPeyton, Jonathan L int main()
51*72ada5aeSPeyton, Jonathan L {
52*72ada5aeSPeyton, Jonathan L int i1,i2,i3,i4;
53*72ada5aeSPeyton, Jonathan L omp_set_num_threads(2);
54*72ada5aeSPeyton, Jonathan L #pragma omp parallel
55*72ada5aeSPeyton, Jonathan L {
56*72ada5aeSPeyton, Jonathan L #pragma omp single nowait
57*72ada5aeSPeyton, Jonathan L {
58*72ada5aeSPeyton, Jonathan L int t = omp_get_thread_num();
59*72ada5aeSPeyton, Jonathan L #pragma omp task depend(in: i1, i2)
60*72ada5aeSPeyton, Jonathan L { int th = omp_get_thread_num();
61*72ada5aeSPeyton, Jonathan L printf("task 0_%d, th %d\n", t, th);
62*72ada5aeSPeyton, Jonathan L my_sleep(DELAY); }
63*72ada5aeSPeyton, Jonathan L #pragma omp task depend(in: i1, i3)
64*72ada5aeSPeyton, Jonathan L { int th = omp_get_thread_num();
65*72ada5aeSPeyton, Jonathan L printf("task 1_%d, th %d\n", t, th);
66*72ada5aeSPeyton, Jonathan L my_sleep(DELAY); }
67*72ada5aeSPeyton, Jonathan L #pragma omp task depend(in: i2) depend(out: i1)
68*72ada5aeSPeyton, Jonathan L { int th = omp_get_thread_num();
69*72ada5aeSPeyton, Jonathan L printf("task 2_%d, th %d\n", t, th);
70*72ada5aeSPeyton, Jonathan L my_sleep(DELAY); }
71*72ada5aeSPeyton, Jonathan L #pragma omp task depend(in: i1)
72*72ada5aeSPeyton, Jonathan L { int th = omp_get_thread_num();
73*72ada5aeSPeyton, Jonathan L printf("task 3_%d, th %d\n", t, th);
74*72ada5aeSPeyton, Jonathan L my_sleep(DELAY); }
75*72ada5aeSPeyton, Jonathan L #pragma omp task depend(out: i2)
76*72ada5aeSPeyton, Jonathan L { int th = omp_get_thread_num();
77*72ada5aeSPeyton, Jonathan L printf("task 4_%d, th %d\n", t, th);
78*72ada5aeSPeyton, Jonathan L my_sleep(DELAY+0.1); } // wait a bit longer than task 3
79*72ada5aeSPeyton, Jonathan L #pragma omp task depend(out: i3)
80*72ada5aeSPeyton, Jonathan L { int th = omp_get_thread_num();
81*72ada5aeSPeyton, Jonathan L printf("task 5_%d, th %d\n", t, th);
82*72ada5aeSPeyton, Jonathan L my_sleep(DELAY); }
83*72ada5aeSPeyton, Jonathan L
84*72ada5aeSPeyton, Jonathan L #pragma omp task depend(mutexinoutset: i1, i4)
85*72ada5aeSPeyton, Jonathan L { mutex_task(6); }
86*72ada5aeSPeyton, Jonathan L #pragma omp task depend(mutexinoutset: i1, i4)
87*72ada5aeSPeyton, Jonathan L { mutex_task(7); }
88*72ada5aeSPeyton, Jonathan L
89*72ada5aeSPeyton, Jonathan L #pragma omp task depend(in: i1)
90*72ada5aeSPeyton, Jonathan L { int th = omp_get_thread_num();
91*72ada5aeSPeyton, Jonathan L printf("task 8_%d, th %d\n", t, th);
92*72ada5aeSPeyton, Jonathan L my_sleep(DELAY); }
93*72ada5aeSPeyton, Jonathan L } // single
94*72ada5aeSPeyton, Jonathan L } // parallel
95*72ada5aeSPeyton, Jonathan L if (err == 0) {
96*72ada5aeSPeyton, Jonathan L printf("passed\n");
97*72ada5aeSPeyton, Jonathan L return 0;
98*72ada5aeSPeyton, Jonathan L } else {
99*72ada5aeSPeyton, Jonathan L printf("failed\n");
100*72ada5aeSPeyton, Jonathan L return 1;
101*72ada5aeSPeyton, Jonathan L }
102*72ada5aeSPeyton, Jonathan L }
103