xref: /llvm-project/openmp/runtime/test/tasking/omp50_task_depend_mtx3.c (revision 72ada5ae6c5bcc53045eba559666a65a68149e4c)
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