1 // RUN: %libomp-compile-and-run
2 #include <stdio.h>
3 #include "omp_testsuite.h"
4 
5 /*
6  * This test will hang if the nowait is not working properly
7  *
8  * It relies on a one thread skipping to the last single construct to
9  * release the threads in the first three single constructs
10  */
11 volatile int release;
12 volatile int count;
13 
wait_for_release_then_increment(int rank)14 void wait_for_release_then_increment(int rank)
15 {
16   fprintf(stderr, "Thread nr %d enters first section"
17     " and waits.\n", rank);
18   while (release == 0);
19   #pragma omp atomic
20   count++;
21 }
22 
release_and_increment(int rank)23 void release_and_increment(int rank)
24 {
25   fprintf(stderr, "Thread nr %d sets release to 1\n", rank);
26   release = 1;
27   #pragma omp atomic
28   count++;
29 }
30 
test_omp_single_nowait()31 int test_omp_single_nowait()
32 {
33   release = 0;
34   count = 0;
35 
36   #pragma omp parallel num_threads(4)
37   {
38     int rank;
39     rank = omp_get_thread_num ();
40     #pragma omp single nowait
41     {
42       wait_for_release_then_increment(rank);
43     }
44     #pragma omp single nowait
45     {
46       wait_for_release_then_increment(rank);
47     }
48     #pragma omp single nowait
49     {
50       wait_for_release_then_increment(rank);
51     }
52 
53     #pragma omp single
54     {
55       release_and_increment(rank);
56     }
57   }
58   // Check to make sure all four singles were executed
59   return (count==4);
60 } /* end of check_single_nowait*/
61 
main()62 int main()
63 {
64   int i;
65   int num_failed=0;
66 
67   for(i = 0; i < REPETITIONS; i++) {
68     if(!test_omp_single_nowait()) {
69       num_failed++;
70     }
71   }
72   return num_failed;
73 }
74