1// RUN: %libomp-compile-and-run
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <omp.h>
6#include "omp_my_sleep.h"
7
8int a = 0, b = 0;
9int task_grabbed = 0, task_can_proceed = 0;
10int task2_grabbed = 0, task2_can_proceed = 0;
11
12static void wait_on_flag(int *flag) {
13 int flag_value;
14 int timelimit = 30;
15 int secs = 0;
16 do {
17 #pragma omp atomic read
18 flag_value = *flag;
19 my_sleep(1.0);
20 secs++;
21 if (secs == timelimit) {
22 fprintf(stderr, format: "error: timeout in wait_on_flag()\n");
23 exit(EXIT_FAILURE);
24 }
25 } while (flag_value == 0);
26}
27
28static void signal_flag(int *flag) {
29 #pragma omp atomic
30 (*flag)++;
31}
32
33int main(int argc, char** argv) {
34
35 // Ensure two threads are running
36 int num_threads = omp_get_max_threads();
37 if (num_threads < 2)
38 omp_set_num_threads(2);
39
40 #pragma omp parallel shared(a)
41 {
42 int a_value;
43 // Let us be extra safe here
44 if (omp_get_num_threads() > 1) {
45 #pragma omp single nowait
46 {
47 // Schedule independent child task that
48 // waits to be flagged after sebsequent taskwait depend()
49 #pragma omp task
50 {
51 signal_flag(flag: &task_grabbed);
52 wait_on_flag(flag: &task_can_proceed);
53 }
54 // Let another worker thread grab the task to execute
55 wait_on_flag(flag: &task_grabbed);
56 // This should be ignored since the task above has
57 // no dependency information
58 #pragma omp task if(0) depend(inout: a)
59 {}
60 // Signal the independent task to proceed
61 signal_flag(flag: &task_can_proceed);
62
63 // Schedule child task with dependencies that taskwait does
64 // not care about
65 #pragma omp task depend(inout: b)
66 {
67 signal_flag(flag: &task2_grabbed);
68 wait_on_flag(flag: &task2_can_proceed);
69 #pragma omp atomic
70 b++;
71 }
72 // Let another worker thread grab the task to execute
73 wait_on_flag(flag: &task2_grabbed);
74 // This should be ignored since the task above has
75 // dependency information on b instead of a
76 #pragma omp task if(0) depend(inout: a)
77 {}
78 // Signal the task to proceed
79 signal_flag(flag: &task2_can_proceed);
80
81 // Generate one child task for taskwait
82 #pragma omp task shared(a) depend(inout: a)
83 {
84 my_sleep(1.0);
85 #pragma omp atomic
86 a++;
87 }
88 #pragma omp task if(0) depend(inout: a)
89 {}
90
91 #pragma omp atomic read
92 a_value = a;
93
94 if (a_value != 1) {
95 fprintf(stderr, format: "error: dependent task was not executed before "
96 "taskwait finished\n");
97 exit(EXIT_FAILURE);
98 }
99 } // #pragma omp single
100 } // if (num_threads > 1)
101 } // #pragma omp parallel
102
103 return EXIT_SUCCESS;
104}
105

source code of openmp/runtime/test/tasking/taskdep_if0_2.c