forked from OSchip/llvm-project
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:
parent
ca4f02ce53
commit
741b70926f
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue