xref: /llvm-project/openmp/runtime/test/worksharing/for/omp_for_nowait.c (revision 741b70926f76ddca0f75e219a2c6a7001bbb992c)
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 for construct to
9  * release the threads in the first for construct.
10  *
11  * Also, we use static scheduling to guarantee that one
12  * thread will make it to the second for construct.
13  */
14 volatile int release;
15 volatile int count;
16 
wait_for_release_then_increment(int rank)17 void wait_for_release_then_increment(int rank)
18 {
19   fprintf(stderr, "Thread nr %d enters first for construct"
20     " and waits.\n", rank);
21   while (release == 0);
22   #pragma omp atomic
23   count++;
24 }
25 
release_and_increment(int rank)26 void release_and_increment(int rank)
27 {
28   fprintf(stderr, "Thread nr %d sets release to 1\n", rank);
29   release = 1;
30   #pragma omp atomic
31   count++;
32 }
33 
test_omp_for_nowait()34 int test_omp_for_nowait()
35 {
36   release = 0;
37   count = 0;
38 
39   #pragma omp parallel num_threads(4)
40   {
41     int rank;
42     int i;
43 
44     rank = omp_get_thread_num();
45 
46     #pragma omp for schedule(static) nowait
47     for (i = 0; i < 4; i++) {
48       if (i < 3)
49         wait_for_release_then_increment(rank);
50       else {
51         fprintf(stderr, "Thread nr %d enters first for and goes "
52           "immediately to the next for construct to release.\n", rank);
53         #pragma omp atomic
54         count++;
55       }
56     }
57 
58     #pragma omp for schedule(static)
59     for (i = 0; i < 4; i++) {
60         release_and_increment(rank);
61     }
62   }
63   return (count==8);
64 }
65 
main()66 int main()
67 {
68   int i;
69   int num_failed=0;
70 
71   for(i = 0; i < REPETITIONS; i++) {
72     if(!test_omp_for_nowait()) {
73       num_failed++;
74     }
75   }
76   return num_failed;
77 }
78