diff --git a/openmp/runtime/src/kmp_ftn_os.h b/openmp/runtime/src/kmp_ftn_os.h --- a/openmp/runtime/src/kmp_ftn_os.h +++ b/openmp/runtime/src/kmp_ftn_os.h @@ -680,5 +680,6 @@ #define KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME \ GOMP_parallel_loop_maybe_nonmonotonic_runtime #define KMP_API_NAME_GOMP_TEAMS_REG GOMP_teams_reg +#define KMP_API_NAME_GOMP_TASKWAIT_DEPEND GOMP_taskwait_depend #endif /* KMP_FTN_OS_H */ diff --git a/openmp/runtime/src/kmp_gsupport.cpp b/openmp/runtime/src/kmp_gsupport.cpp --- a/openmp/runtime/src/kmp_gsupport.cpp +++ b/openmp/runtime/src/kmp_gsupport.cpp @@ -1850,6 +1850,19 @@ KA_TRACE(20, ("GOMP_teams_reg exit: T#%d\n", gtid)); } +void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKWAIT_DEPEND)(void **depend) { + MKLOC(loc, "GOMP_taskwait_depend"); + int gtid = __kmp_entry_gtid(); + KA_TRACE(20, ("GOMP_taskwait_depend: T#%d\n", gtid)); + kmp_gomp_depends_info_t gomp_depends(depend); + kmp_int32 ndeps = gomp_depends.get_num_deps(); + kmp_depend_info_t dep_list[ndeps]; + for (kmp_int32 i = 0; i < ndeps; i++) + dep_list[i] = gomp_depends.get_kmp_depend(i); + __kmpc_omp_wait_deps(&loc, gtid, ndeps, dep_list, 0, NULL); + KA_TRACE(20, ("GOMP_taskwait_depend exit: T#%d\n", gtid)); +} + /* The following sections of code create aliases for the GOMP_* functions, then create versioned symbols using the assembler directive .symver. This is only pertinent for ELF .so library. The KMP_VERSION_SYMBOL macro is defined in @@ -2022,6 +2035,7 @@ KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME, 50, "GOMP_5.0"); KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TEAMS_REG, 50, "GOMP_5.0"); +KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKWAIT_DEPEND, 50, "GOMP_5.0"); #endif // KMP_USE_VERSION_SYMBOLS diff --git a/openmp/runtime/test/tasking/omp50_taskwait_depend.c b/openmp/runtime/test/tasking/omp50_taskwait_depend.c new file mode 100644 --- /dev/null +++ b/openmp/runtime/test/tasking/omp50_taskwait_depend.c @@ -0,0 +1,71 @@ +// RUN: %libomp-compile-and-run +// UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-8 +// UNSUPPORTED: clang, icc + +#include +#include +#include +#include "omp_my_sleep.h" + +#define NUM_TASKS 200 + +int a = 0; +int b = 0; +volatile int flag = 0; + +int main(int argc, char** argv) { + #pragma omp parallel shared(a) + { + #pragma omp single nowait + { + int i; + for (i = 0; i < NUM_TASKS; ++i) { + // Generate multiple children that should not have + // to execute before taskwait depend() + #pragma omp task shared(a) + { + // These children wait for the signal after taskwait + double elapsed_time = 0.0; + while (flag == 0) { + my_sleep(1.0); + elapsed_time += 1.0; + if (elapsed_time > 30.0) { + fprintf(stderr, "tasks were never signaled!\n"); + exit(1); + } + } + #pragma omp atomic + b++; + } + } + + // Generate one child for taskwait to wait on + for (i = 0; i < NUM_TASKS; ++i) { + #pragma omp task shared(a) depend(inout: a) + { + a++; + } + } + + #pragma omp taskwait depend(inout: a) + // The test will loop forever if the taskwait is a normal + // taskwait that waits on all children regardless of depend() + // because the children are waiting for the flag to be set + + if (a != NUM_TASKS) { + fprintf(stderr, "taskwait did not wait for task!\n"); + exit(1); + } + if (b) { + fprintf(stderr, "tasks were signaled prematurely\n"); + exit(1); + } + flag = 1; + } + } + if (b != NUM_TASKS) { + fprintf(stderr, "non-depend tasks did not execute properly\n"); + exit(1); + } + return 0; +}