1// RUN: %libomp-compile-and-run
2// UNSUPPORTED: gcc
3// This test is incompatible with gcc because of the explicit call to
4// __kmpc_doacross_fini(). gcc relies on an implicit call to this function
5// when the last iteration is executed inside the GOMP_loop_*_next() functions.
6// Hence, in gcc, having the explicit call leads to __kmpc_doacross_fini()
7// being called twice.
8#include <stdio.h>
9
10#define N 1000
11
12struct dim {
13 long long lo; // lower
14 long long up; // upper
15 long long st; // stride
16};
17extern void __kmpc_doacross_init(void*, int, int, struct dim *);
18extern void __kmpc_doacross_wait(void*, int, long long*);
19extern void __kmpc_doacross_post(void*, int, long long*);
20extern void __kmpc_doacross_fini(void*, int);
21extern int __kmpc_global_thread_num(void*);
22
23int main()
24{
25 int i;
26 int iter[N];
27 struct dim dims;
28 for( i = 0; i < N; ++i )
29 iter[i] = 1;
30 dims.lo = 1;
31 dims.up = N-1;
32 dims.st = 1;
33 #pragma omp parallel num_threads(4)
34 {
35 int i, gtid;
36 long long vec;
37 gtid = __kmpc_global_thread_num(NULL);
38 __kmpc_doacross_init(NULL,gtid,1,&dims); // thread starts the loop
39 #pragma omp for nowait schedule(dynamic)
40 for( i = 1; i < N; ++i )
41 {
42 // runtime call corresponding to #pragma omp ordered depend(sink:i-1)
43 vec=i-1;
44 __kmpc_doacross_wait(NULL,gtid,&vec);
45 // user's code
46 iter[i] = iter[i-1] + 1;
47 // runtime call corresponding to #pragma omp ordered depend(source)
48 vec=i;
49 __kmpc_doacross_post(NULL,gtid,&vec);
50 }
51 // thread finishes the loop (should be before the loop barrier)
52 __kmpc_doacross_fini(NULL,gtid);
53 }
54 if( iter[N-1] == N ) {
55 printf(format: "passed\n");
56 } else {
57 printf(format: "failed %d != %d\n", iter[N-1], N);
58 return 1;
59 }
60 return 0;
61}
62
63

source code of openmp/runtime/test/worksharing/for/kmp_doacross_check.c