// RUN: %libomp-compile-and-run // UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-8 // support for taskwait with depend clause introduced in clang-14 // UNSUPPORTED: clang-5, clang-6, clang-6, clang-8, clang-9, clang-10, clang-11, // clang-12, clang-13 // icc does not yet support taskwait with depend clause // XFAIL: icc #include #include #include #include "omp_my_sleep.h" int a = 0, b = 0; int task_grabbed = 0, task_can_proceed = 0; int task2_grabbed = 0, task2_can_proceed = 0; static void wait_on_flag(int *flag) { int flag_value; int timelimit = 30; int secs = 0; do { #pragma omp atomic read flag_value = *flag; my_sleep(1.0); secs++; if (secs == timelimit) { fprintf(stderr, "error: timeout in wait_on_flag()\n"); exit(EXIT_FAILURE); } } while (flag_value == 0); } static void signal_flag(int *flag) { #pragma omp atomic (*flag)++; } int main(int argc, char** argv) { // Ensure two threads are running int num_threads = omp_get_max_threads(); if (num_threads < 2) omp_set_num_threads(2); #pragma omp parallel shared(a) { int a_value; // Let us be extra safe here if (omp_get_num_threads() > 1) { #pragma omp single nowait { // Schedule independent child task that // waits to be flagged after sebsequent taskwait depend() #pragma omp task { signal_flag(&task_grabbed); wait_on_flag(&task_can_proceed); } // Let another worker thread grab the task to execute wait_on_flag(&task_grabbed); // This should be ignored since the task above has // no dependency information #pragma omp taskwait depend(inout: a) // Signal the independent task to proceed signal_flag(&task_can_proceed); // Schedule child task with dependencies that taskwait does // not care about #pragma omp task depend(inout: b) { signal_flag(&task2_grabbed); wait_on_flag(&task2_can_proceed); #pragma omp atomic b++; } // Let another worker thread grab the task to execute wait_on_flag(&task2_grabbed); // This should be ignored since the task above has // dependency information on b instead of a #pragma omp taskwait depend(inout: a) // Signal the task to proceed signal_flag(&task2_can_proceed); // Generate one child task for taskwait #pragma omp task shared(a) depend(inout: a) { my_sleep(1.0); #pragma omp atomic a++; } #pragma omp taskwait depend(inout: a) #pragma omp atomic read a_value = a; if (a_value != 1) { fprintf(stderr, "error: dependent task was not executed before " "taskwait finished\n"); exit(EXIT_FAILURE); } } // #pragma omp single } // if (num_threads > 1) } // #pragma omp parallel return EXIT_SUCCESS; }