From 741b70926f76ddca0f75e219a2c6a7001bbb992c Mon Sep 17 00:00:00 2001 From: Jonathan Peyton Date: Wed, 6 Jul 2016 17:26:12 +0000 Subject: [PATCH] Fix the nowait tests for omp for and omp single These tests are now modeled after the sections nowait test where threads wait to be released in the first construct (either for or single) and the last thread skips the last for/single construct and releases those threads. If the test fails, then it hangs because an unnecessary barrier is executed in between the constructs. llvm-svn: 274641 --- .../test/worksharing/for/omp_for_nowait.c | 64 +++++++++++----- .../worksharing/single/omp_single_nowait.c | 76 +++++++++++-------- 2 files changed, 90 insertions(+), 50 deletions(-) diff --git a/openmp/runtime/test/worksharing/for/omp_for_nowait.c b/openmp/runtime/test/worksharing/for/omp_for_nowait.c index 37509458ca3f..95a477538f2a 100644 --- a/openmp/runtime/test/worksharing/for/omp_for_nowait.c +++ b/openmp/runtime/test/worksharing/for/omp_for_nowait.c @@ -1,42 +1,66 @@ // RUN: %libomp-compile-and-run #include #include "omp_testsuite.h" -#include "omp_my_sleep.h" + +/* + * This test will hang if the nowait is not working properly. + * + * It relies on a thread skipping to the second for construct to + * release the threads in the first for construct. + * + * Also, we use static scheduling to guarantee that one + * thread will make it to the second for construct. + */ +volatile int release; +volatile int count; + +void wait_for_release_then_increment(int rank) +{ + fprintf(stderr, "Thread nr %d enters first for construct" + " and waits.\n", rank); + while (release == 0); + #pragma omp atomic + count++; +} + +void release_and_increment(int rank) +{ + fprintf(stderr, "Thread nr %d sets release to 1\n", rank); + release = 1; + #pragma omp atomic + count++; +} int test_omp_for_nowait() { - int result; - int count; - int j; - int myarray[LOOPCOUNT]; - - result = 0; + release = 0; count = 0; - #pragma omp parallel + #pragma omp parallel num_threads(4) { int rank; int i; rank = omp_get_thread_num(); - #pragma omp for nowait - for (i = 0; i < LOOPCOUNT; i++) { - if (i == 0) { - my_sleep(SLEEPTIME); - count = 1; - #pragma omp flush(count) + #pragma omp for schedule(static) nowait + for (i = 0; i < 4; i++) { + if (i < 3) + wait_for_release_then_increment(rank); + else { + fprintf(stderr, "Thread nr %d enters first for and goes " + "immediately to the next for construct to release.\n", rank); + #pragma omp atomic + count++; } } - #pragma omp for - for (i = 0; i < LOOPCOUNT; i++) { - #pragma omp flush(count) - if (count == 0) - result = 1; + #pragma omp for schedule(static) + for (i = 0; i < 4; i++) { + release_and_increment(rank); } } - return result; + return (count==8); } int main() diff --git a/openmp/runtime/test/worksharing/single/omp_single_nowait.c b/openmp/runtime/test/worksharing/single/omp_single_nowait.c index 99fc3201ae0a..22f8930d9eb4 100644 --- a/openmp/runtime/test/worksharing/single/omp_single_nowait.c +++ b/openmp/runtime/test/worksharing/single/omp_single_nowait.c @@ -2,45 +2,61 @@ #include #include "omp_testsuite.h" -int my_iterations; -#pragma omp threadprivate(my_iterations) +/* + * This test will hang if the nowait is not working properly + * + * It relies on a one thread skipping to the last single construct to + * release the threads in the first three single constructs + */ +volatile int release; +volatile int count; + +void wait_for_release_then_increment(int rank) +{ + fprintf(stderr, "Thread nr %d enters first section" + " and waits.\n", rank); + while (release == 0); + #pragma omp atomic + count++; +} + +void release_and_increment(int rank) +{ + fprintf(stderr, "Thread nr %d sets release to 1\n", rank); + release = 1; + #pragma omp atomic + count++; +} int test_omp_single_nowait() { - int nr_iterations; - int total_iterations = 0; - int i; + release = 0; + count = 0; - nr_iterations = 0; - my_iterations = 0; - - #pragma omp parallel private(i) + #pragma omp parallel num_threads(4) { - for (i = 0; i < LOOPCOUNT; i++) { - #pragma omp single nowait - { - #pragma omp atomic - nr_iterations++; - } - } - } - - #pragma omp parallel private(i) - { - my_iterations = 0; - for (i = 0; i < LOOPCOUNT; i++) { - #pragma omp single nowait - { - my_iterations++; - } - } - #pragma omp critical + int rank; + rank = omp_get_thread_num (); + #pragma omp single nowait { - total_iterations += my_iterations; + wait_for_release_then_increment(rank); + } + #pragma omp single nowait + { + wait_for_release_then_increment(rank); + } + #pragma omp single nowait + { + wait_for_release_then_increment(rank); } + #pragma omp single + { + release_and_increment(rank); + } } - return ((nr_iterations == LOOPCOUNT) && (total_iterations == LOOPCOUNT)); + // Check to make sure all four singles were executed + return (count==4); } /* end of check_single_nowait*/ int main()