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
This commit is contained in:
Jonathan Peyton 2016-07-06 17:26:12 +00:00
parent ca4f02ce53
commit 741b70926f
2 changed files with 90 additions and 50 deletions

View File

@ -1,42 +1,66 @@
// RUN: %libomp-compile-and-run
#include <stdio.h>
#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()

View File

@ -2,45 +2,61 @@
#include <stdio.h>
#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()