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 8 int a = 0, b = 0; 9 int task_grabbed = 0, task_can_proceed = 0; 10 int task2_grabbed = 0, task2_can_proceed = 0; 11 wait_on_flag(int * flag)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, "error: timeout in wait_on_flag()\n"); 23 exit(EXIT_FAILURE); 24 } 25 } while (flag_value == 0); 26 } 27 signal_flag(int * flag)28static void signal_flag(int *flag) { 29 #pragma omp atomic 30 (*flag)++; 31 } 32 main(int argc,char ** argv)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(&task_grabbed); 52 wait_on_flag(&task_can_proceed); 53 } 54 // Let another worker thread grab the task to execute 55 wait_on_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(&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(&task2_grabbed); 68 wait_on_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(&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(&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, "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