This rewrite of the omp_sections_nowait.c test file causes it to hang if the nowait is not respected. If the nowait isn't respected, the lone thread which can escape the first sections construct will just sleep at a barrier which shouldn't exist. All reliance on timers is taken out. For good measure, the test makes sure that all eight sections are executed as well. The test should take no longer than a few seconds on any modern machine. Differential Revision: http://reviews.llvm.org/D21842 llvm-svn: 274151
105 lines
2.2 KiB
C
105 lines
2.2 KiB
C
// RUN: %libomp-compile-and-run
|
|
#include <stdio.h>
|
|
#include "omp_testsuite.h"
|
|
|
|
/*
|
|
* This test will hang if the nowait is not working properly
|
|
*
|
|
* It relies on a thread skipping to the second sections construct to
|
|
* release the threads in the first sections construct
|
|
*
|
|
* Also, since scheduling of sections is implementation defined, it is
|
|
* necessary to have all four sections in the second sections construct
|
|
* release the threads since we can't guarantee which section a single thread
|
|
* will execute.
|
|
*/
|
|
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 flush(release)
|
|
#pragma omp atomic
|
|
count++;
|
|
}
|
|
|
|
int test_omp_sections_nowait()
|
|
{
|
|
release = 0;
|
|
count = 0;
|
|
|
|
#pragma omp parallel num_threads(4)
|
|
{
|
|
int rank;
|
|
rank = omp_get_thread_num ();
|
|
#pragma omp sections nowait
|
|
{
|
|
#pragma omp section
|
|
{
|
|
wait_for_release_then_increment(rank);
|
|
}
|
|
#pragma omp section
|
|
{
|
|
wait_for_release_then_increment(rank);
|
|
}
|
|
#pragma omp section
|
|
{
|
|
wait_for_release_then_increment(rank);
|
|
}
|
|
#pragma omp section
|
|
{
|
|
fprintf(stderr, "Thread nr %d enters first sections and goes "
|
|
"immediately to next sections construct to release.\n", rank);
|
|
#pragma omp atomic
|
|
count++;
|
|
}
|
|
}
|
|
/* Begin of second sections environment */
|
|
#pragma omp sections
|
|
{
|
|
#pragma omp section
|
|
{
|
|
release_and_increment(rank);
|
|
}
|
|
#pragma omp section
|
|
{
|
|
release_and_increment(rank);
|
|
}
|
|
#pragma omp section
|
|
{
|
|
release_and_increment(rank);
|
|
}
|
|
#pragma omp section
|
|
{
|
|
release_and_increment(rank);
|
|
}
|
|
}
|
|
}
|
|
// Check to make sure all eight sections were executed
|
|
return (count==8);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int i;
|
|
int num_failed=0;
|
|
|
|
for(i = 0; i < REPETITIONS; i++) {
|
|
if(!test_omp_sections_nowait()) {
|
|
num_failed++;
|
|
}
|
|
}
|
|
return num_failed;
|
|
}
|