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 | |
19 | void wait_for_release_then_increment(int rank) |
20 | { |
21 | fprintf(stderr, format: "Thread nr %d enters first section" |
22 | " and waits.\n" , rank); |
23 | while (release == 0); |
24 | #pragma omp atomic |
25 | count++; |
26 | } |
27 | |
28 | void release_and_increment(int rank) |
29 | { |
30 | fprintf(stderr, format: "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 | |
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, format: "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 | |
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 | |