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 thread skipping to the second sections construct to
9  * release the threads in the first sections construct
10  *
11  * Also, since scheduling of sections is implementation defined, it is
12  * necessary to have all four sections in the second sections construct
13  * release the threads since we can't guarantee which section a single thread
14  * will execute.
15  */
16 volatile int release;
17 volatile int count;
18 
wait_for_release_then_increment(int rank)19 void wait_for_release_then_increment(int rank)
20 {
21   fprintf(stderr, "Thread nr %d enters first section"
22     " and waits.\n", rank);
23   while (release == 0);
24   #pragma omp atomic
25   count++;
26 }
27 
release_and_increment(int rank)28 void release_and_increment(int rank)
29 {
30   fprintf(stderr, "Thread nr %d sets release to 1\n", rank);
31   release = 1;
32   #pragma omp flush(release)
33   #pragma omp atomic
34   count++;
35 }
36 
test_omp_sections_nowait()37 int test_omp_sections_nowait()
38 {
39   release = 0;
40   count = 0;
41 
42   #pragma omp parallel num_threads(4)
43   {
44     int rank;
45     rank = omp_get_thread_num ();
46     #pragma omp sections nowait
47     {
48       #pragma omp section
49       {
50         wait_for_release_then_increment(rank);
51       }
52       #pragma omp section
53       {
54         wait_for_release_then_increment(rank);
55       }
56       #pragma omp section
57       {
58         wait_for_release_then_increment(rank);
59       }
60       #pragma omp section
61       {
62         fprintf(stderr, "Thread nr %d enters first sections and goes "
63           "immediately to next sections construct to release.\n", rank);
64         #pragma omp atomic
65         count++;
66       }
67     }
68     /* Begin of second sections environment */
69     #pragma omp sections
70     {
71       #pragma omp section
72       {
73         release_and_increment(rank);
74       }
75       #pragma omp section
76       {
77         release_and_increment(rank);
78       }
79       #pragma omp section
80       {
81         release_and_increment(rank);
82       }
83       #pragma omp section
84       {
85         release_and_increment(rank);
86       }
87     }
88   }
89   // Check to make sure all eight sections were executed
90   return (count==8);
91 }
92 
main()93 int main()
94 {
95   int i;
96   int num_failed=0;
97 
98   for(i = 0; i < REPETITIONS; i++) {
99     if(!test_omp_sections_nowait()) {
100       num_failed++;
101     }
102   }
103   return num_failed;
104 }
105