xref: /llvm-project/openmp/runtime/test/ompt/tasks/kmp_task_depend_all.c (revision 6ef16f2618093e3f3def6e905437013de71785f5)
1*6ef16f26SJoachim Jenke // RUN: %libomp-compile-and-run | FileCheck %s
2*6ef16f26SJoachim Jenke // REQUIRES: ompt
3*6ef16f26SJoachim Jenke 
4*6ef16f26SJoachim Jenke // RUN: %libomp-compile-and-run
5*6ef16f26SJoachim Jenke // The runtime currently does not get dependency information from GCC.
6*6ef16f26SJoachim Jenke // UNSUPPORTED: gcc
7*6ef16f26SJoachim Jenke 
8*6ef16f26SJoachim Jenke // Tests OMP 5.x task dependence "omp_all_memory",
9*6ef16f26SJoachim Jenke // emulates compiler codegen versions for new dep kind
10*6ef16f26SJoachim Jenke //
11*6ef16f26SJoachim Jenke // Task tree created:
12*6ef16f26SJoachim Jenke //      task0 - task1 (in: i1, i2)
13*6ef16f26SJoachim Jenke //             \
14*6ef16f26SJoachim Jenke //        task2 (inoutset: i2), (in: i1)
15*6ef16f26SJoachim Jenke //             /
16*6ef16f26SJoachim Jenke //        task3 (omp_all_memory) via flag=0x80
17*6ef16f26SJoachim Jenke //             /
18*6ef16f26SJoachim Jenke //      task4 - task5 (in: i1, i2)
19*6ef16f26SJoachim Jenke //           /
20*6ef16f26SJoachim Jenke //       task6 (omp_all_memory) via addr=-1
21*6ef16f26SJoachim Jenke //           /
22*6ef16f26SJoachim Jenke //       task7 (omp_all_memory) via flag=0x80
23*6ef16f26SJoachim Jenke //           /
24*6ef16f26SJoachim Jenke //       task8 (in: i3)
25*6ef16f26SJoachim Jenke //
26*6ef16f26SJoachim Jenke 
27*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
28*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
29*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
30*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
31*6ef16f26SJoachim Jenke 
32*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
33*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
34*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
35*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
36*6ef16f26SJoachim Jenke 
37*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
38*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
39*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_inoutset
40*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
41*6ef16f26SJoachim Jenke 
42*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
43*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
44*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_out_all_memory
45*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
46*6ef16f26SJoachim Jenke 
47*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
48*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
49*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
50*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
51*6ef16f26SJoachim Jenke 
52*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
53*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
54*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
55*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
56*6ef16f26SJoachim Jenke 
57*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
58*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_out_all_memory
59*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=1
60*6ef16f26SJoachim Jenke 
61*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
62*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_out_all_memory
63*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_mutexinoutset
64*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
65*6ef16f26SJoachim Jenke 
66*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
67*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
68*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=1
69*6ef16f26SJoachim Jenke 
70*6ef16f26SJoachim Jenke #include "callback.h"
71*6ef16f26SJoachim Jenke #include <stdio.h>
72*6ef16f26SJoachim Jenke #include <omp.h>
73*6ef16f26SJoachim Jenke 
74*6ef16f26SJoachim Jenke #ifdef _WIN32
75*6ef16f26SJoachim Jenke #include <windows.h>
76*6ef16f26SJoachim Jenke #define mysleep(n) Sleep(n)
77*6ef16f26SJoachim Jenke #else
78*6ef16f26SJoachim Jenke #include <unistd.h>
79*6ef16f26SJoachim Jenke #define mysleep(n) usleep((n)*1000)
80*6ef16f26SJoachim Jenke #endif
81*6ef16f26SJoachim Jenke 
82*6ef16f26SJoachim Jenke // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
83*6ef16f26SJoachim Jenke static int checker = 0;
84*6ef16f26SJoachim Jenke static int err = 0;
85*6ef16f26SJoachim Jenke #ifndef DELAY
86*6ef16f26SJoachim Jenke #define DELAY 100
87*6ef16f26SJoachim Jenke #endif
88*6ef16f26SJoachim Jenke 
89*6ef16f26SJoachim Jenke // ---------------------------------------------------------------------------
90*6ef16f26SJoachim Jenke // internal data to emulate compiler codegen
91*6ef16f26SJoachim Jenke typedef struct DEP {
92*6ef16f26SJoachim Jenke   size_t addr;
93*6ef16f26SJoachim Jenke   size_t len;
94*6ef16f26SJoachim Jenke   unsigned char flags;
95*6ef16f26SJoachim Jenke } dep;
96*6ef16f26SJoachim Jenke #define DEP_ALL_MEM 0x80
97*6ef16f26SJoachim Jenke typedef struct task {
98*6ef16f26SJoachim Jenke   void **shareds;
99*6ef16f26SJoachim Jenke   void *entry;
100*6ef16f26SJoachim Jenke   int part_id;
101*6ef16f26SJoachim Jenke   void *destr_thunk;
102*6ef16f26SJoachim Jenke   int priority;
103*6ef16f26SJoachim Jenke   long long device_id;
104*6ef16f26SJoachim Jenke   int f_priv;
105*6ef16f26SJoachim Jenke } task_t;
106*6ef16f26SJoachim Jenke #define TIED 1
107*6ef16f26SJoachim Jenke typedef int (*entry_t)(int, task_t *);
108*6ef16f26SJoachim Jenke typedef struct ID {
109*6ef16f26SJoachim Jenke   int reserved_1;
110*6ef16f26SJoachim Jenke   int flags;
111*6ef16f26SJoachim Jenke   int reserved_2;
112*6ef16f26SJoachim Jenke   int reserved_3;
113*6ef16f26SJoachim Jenke   char *psource;
114*6ef16f26SJoachim Jenke } id;
115*6ef16f26SJoachim Jenke // thunk routine for tasks with ALL dependency
thunk_m(int gtid,task_t * ptask)116*6ef16f26SJoachim Jenke int thunk_m(int gtid, task_t *ptask) {
117*6ef16f26SJoachim Jenke   int lcheck, th;
118*6ef16f26SJoachim Jenke #pragma omp atomic capture
119*6ef16f26SJoachim Jenke   lcheck = ++checker;
120*6ef16f26SJoachim Jenke   th = omp_get_thread_num();
121*6ef16f26SJoachim Jenke   printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
122*6ef16f26SJoachim Jenke   if (lcheck != 1) { // no more than 1 task at a time
123*6ef16f26SJoachim Jenke     err++;
124*6ef16f26SJoachim Jenke     printf("Error m1, checker %d != 1\n", lcheck);
125*6ef16f26SJoachim Jenke   }
126*6ef16f26SJoachim Jenke   mysleep(DELAY);
127*6ef16f26SJoachim Jenke #pragma omp atomic read
128*6ef16f26SJoachim Jenke   lcheck = checker; // must still be equal to 1
129*6ef16f26SJoachim Jenke   if (lcheck != 1) {
130*6ef16f26SJoachim Jenke     err++;
131*6ef16f26SJoachim Jenke     printf("Error m2, checker %d != 1\n", lcheck);
132*6ef16f26SJoachim Jenke   }
133*6ef16f26SJoachim Jenke #pragma omp atomic
134*6ef16f26SJoachim Jenke   --checker;
135*6ef16f26SJoachim Jenke   return 0;
136*6ef16f26SJoachim Jenke }
137*6ef16f26SJoachim Jenke // thunk routine for tasks with inoutset dependency
thunk_s(int gtid,task_t * ptask)138*6ef16f26SJoachim Jenke int thunk_s(int gtid, task_t *ptask) {
139*6ef16f26SJoachim Jenke   int lcheck, th;
140*6ef16f26SJoachim Jenke #pragma omp atomic capture
141*6ef16f26SJoachim Jenke   lcheck = ++checker; // 1
142*6ef16f26SJoachim Jenke   th = omp_get_thread_num();
143*6ef16f26SJoachim Jenke   printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
144*6ef16f26SJoachim Jenke   if (lcheck != 1) { // no more than 1 task at a time
145*6ef16f26SJoachim Jenke     err++;
146*6ef16f26SJoachim Jenke     printf("Error s1, checker %d != 1\n", lcheck);
147*6ef16f26SJoachim Jenke   }
148*6ef16f26SJoachim Jenke   mysleep(DELAY);
149*6ef16f26SJoachim Jenke #pragma omp atomic read
150*6ef16f26SJoachim Jenke   lcheck = checker; // must still be equal to 1
151*6ef16f26SJoachim Jenke   if (lcheck != 1) {
152*6ef16f26SJoachim Jenke     err++;
153*6ef16f26SJoachim Jenke     printf("Error s2, checker %d != 1\n", lcheck);
154*6ef16f26SJoachim Jenke   }
155*6ef16f26SJoachim Jenke #pragma omp atomic
156*6ef16f26SJoachim Jenke   --checker;
157*6ef16f26SJoachim Jenke   return 0;
158*6ef16f26SJoachim Jenke }
159*6ef16f26SJoachim Jenke 
160*6ef16f26SJoachim Jenke #ifdef __cplusplus
161*6ef16f26SJoachim Jenke extern "C" {
162*6ef16f26SJoachim Jenke #endif
163*6ef16f26SJoachim Jenke int __kmpc_global_thread_num(id *);
164*6ef16f26SJoachim Jenke task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,
165*6ef16f26SJoachim Jenke                               size_t shar, entry_t rtn);
166*6ef16f26SJoachim Jenke int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,
167*6ef16f26SJoachim Jenke                               dep *dep_lst, int nd_noalias, dep *noalias_lst);
168*6ef16f26SJoachim Jenke static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};
169*6ef16f26SJoachim Jenke #ifdef __cplusplus
170*6ef16f26SJoachim Jenke } // extern "C"
171*6ef16f26SJoachim Jenke #endif
172*6ef16f26SJoachim Jenke // End of internal data
173*6ef16f26SJoachim Jenke // ---------------------------------------------------------------------------
174*6ef16f26SJoachim Jenke 
main()175*6ef16f26SJoachim Jenke int main() {
176*6ef16f26SJoachim Jenke   int i1, i2, i3;
177*6ef16f26SJoachim Jenke   omp_set_num_threads(8);
178*6ef16f26SJoachim Jenke   omp_set_dynamic(0);
179*6ef16f26SJoachim Jenke #pragma omp parallel
180*6ef16f26SJoachim Jenke   {
181*6ef16f26SJoachim Jenke #pragma omp single nowait
182*6ef16f26SJoachim Jenke     {
183*6ef16f26SJoachim Jenke       dep sdep[2];
184*6ef16f26SJoachim Jenke       task_t *ptr;
185*6ef16f26SJoachim Jenke       int gtid = __kmpc_global_thread_num(&loc);
186*6ef16f26SJoachim Jenke       int t = omp_get_thread_num();
187*6ef16f26SJoachim Jenke #pragma omp task depend(in : i1, i2)
188*6ef16f26SJoachim Jenke       { // task 0
189*6ef16f26SJoachim Jenke         int lcheck, th;
190*6ef16f26SJoachim Jenke #pragma omp atomic capture
191*6ef16f26SJoachim Jenke         lcheck = ++checker; // 1 or 2
192*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
193*6ef16f26SJoachim Jenke         printf("task 0_%d, th %d, checker %d\n", t, th, lcheck);
194*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
195*6ef16f26SJoachim Jenke           err++; // no more than 2 tasks concurrently
196*6ef16f26SJoachim Jenke           printf("Error1, checker %d, not 1 or 2\n", lcheck);
197*6ef16f26SJoachim Jenke         }
198*6ef16f26SJoachim Jenke         mysleep(DELAY);
199*6ef16f26SJoachim Jenke #pragma omp atomic read
200*6ef16f26SJoachim Jenke         lcheck = checker; // 1 or 2
201*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
202*6ef16f26SJoachim Jenke #pragma omp atomic
203*6ef16f26SJoachim Jenke           err++;
204*6ef16f26SJoachim Jenke           printf("Error2, checker %d, not 1 or 2\n", lcheck);
205*6ef16f26SJoachim Jenke         }
206*6ef16f26SJoachim Jenke #pragma omp atomic
207*6ef16f26SJoachim Jenke         --checker;
208*6ef16f26SJoachim Jenke       }
209*6ef16f26SJoachim Jenke #pragma omp task depend(in : i1, i2)
210*6ef16f26SJoachim Jenke       { // task 1
211*6ef16f26SJoachim Jenke         int lcheck, th;
212*6ef16f26SJoachim Jenke #pragma omp atomic capture
213*6ef16f26SJoachim Jenke         lcheck = ++checker; // 1 or 2
214*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
215*6ef16f26SJoachim Jenke         printf("task 1_%d, th %d, checker %d\n", t, th, lcheck);
216*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
217*6ef16f26SJoachim Jenke           err++; // no more than 2 tasks concurrently
218*6ef16f26SJoachim Jenke           printf("Error3, checker %d, not 1 or 2\n", lcheck);
219*6ef16f26SJoachim Jenke         }
220*6ef16f26SJoachim Jenke         mysleep(DELAY);
221*6ef16f26SJoachim Jenke #pragma omp atomic read
222*6ef16f26SJoachim Jenke         lcheck = checker; // 1 or 2
223*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
224*6ef16f26SJoachim Jenke           err++;
225*6ef16f26SJoachim Jenke           printf("Error4, checker %d, not 1 or 2\n", lcheck);
226*6ef16f26SJoachim Jenke         }
227*6ef16f26SJoachim Jenke #pragma omp atomic
228*6ef16f26SJoachim Jenke         --checker;
229*6ef16f26SJoachim Jenke       }
230*6ef16f26SJoachim Jenke       // compiler codegen start
231*6ef16f26SJoachim Jenke       // task2
232*6ef16f26SJoachim Jenke       ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);
233*6ef16f26SJoachim Jenke       sdep[0].addr = (size_t)&i1;
234*6ef16f26SJoachim Jenke       sdep[0].len = 0; // not used
235*6ef16f26SJoachim Jenke       sdep[0].flags = 1; // IN
236*6ef16f26SJoachim Jenke       sdep[1].addr = (size_t)&i2;
237*6ef16f26SJoachim Jenke       sdep[1].len = 0; // not used
238*6ef16f26SJoachim Jenke       sdep[1].flags = 8; // INOUTSET
239*6ef16f26SJoachim Jenke       ptr->f_priv = t + 10; // init single first-private variable
240*6ef16f26SJoachim Jenke       __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
241*6ef16f26SJoachim Jenke 
242*6ef16f26SJoachim Jenke       // task3
243*6ef16f26SJoachim Jenke       ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
244*6ef16f26SJoachim Jenke       sdep[0].addr = (size_t)&i1; // to be ignored
245*6ef16f26SJoachim Jenke       sdep[0].len = 0; // not used
246*6ef16f26SJoachim Jenke       sdep[0].flags = 1; // IN
247*6ef16f26SJoachim Jenke       sdep[1].addr = 0;
248*6ef16f26SJoachim Jenke       sdep[1].len = 0; // not used
249*6ef16f26SJoachim Jenke       sdep[1].flags = DEP_ALL_MEM; // omp_all_memory
250*6ef16f26SJoachim Jenke       ptr->f_priv = t + 20; // init single first-private variable
251*6ef16f26SJoachim Jenke       __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
252*6ef16f26SJoachim Jenke       // compiler codegen end
253*6ef16f26SJoachim Jenke #pragma omp task depend(in : i1, i2)
254*6ef16f26SJoachim Jenke       { // task 4
255*6ef16f26SJoachim Jenke         int lcheck, th;
256*6ef16f26SJoachim Jenke #pragma omp atomic capture
257*6ef16f26SJoachim Jenke         lcheck = ++checker; // 1 or 2
258*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
259*6ef16f26SJoachim Jenke         printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);
260*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
261*6ef16f26SJoachim Jenke           err++; // no more than 2 tasks concurrently
262*6ef16f26SJoachim Jenke           printf("Error5, checker %d, not 1 or 2\n", lcheck);
263*6ef16f26SJoachim Jenke         }
264*6ef16f26SJoachim Jenke         mysleep(DELAY);
265*6ef16f26SJoachim Jenke #pragma omp atomic read
266*6ef16f26SJoachim Jenke         lcheck = checker; // 1 or 2
267*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
268*6ef16f26SJoachim Jenke           err++;
269*6ef16f26SJoachim Jenke           printf("Error6, checker %d, not 1 or 2\n", lcheck);
270*6ef16f26SJoachim Jenke         }
271*6ef16f26SJoachim Jenke #pragma omp atomic
272*6ef16f26SJoachim Jenke         --checker;
273*6ef16f26SJoachim Jenke       }
274*6ef16f26SJoachim Jenke #pragma omp task depend(in : i1, i2)
275*6ef16f26SJoachim Jenke       { // task 5
276*6ef16f26SJoachim Jenke         int lcheck, th;
277*6ef16f26SJoachim Jenke #pragma omp atomic capture
278*6ef16f26SJoachim Jenke         lcheck = ++checker; // 1 or 2
279*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
280*6ef16f26SJoachim Jenke         printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);
281*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
282*6ef16f26SJoachim Jenke           err++; // no more than 2 tasks concurrently
283*6ef16f26SJoachim Jenke           printf("Error7, checker %d, not 1 or 2\n", lcheck);
284*6ef16f26SJoachim Jenke         }
285*6ef16f26SJoachim Jenke         mysleep(DELAY);
286*6ef16f26SJoachim Jenke #pragma omp atomic read
287*6ef16f26SJoachim Jenke         lcheck = checker; // 1 or 2
288*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
289*6ef16f26SJoachim Jenke           err++;
290*6ef16f26SJoachim Jenke           printf("Error8, checker %d, not 1 or 2\n", lcheck);
291*6ef16f26SJoachim Jenke         }
292*6ef16f26SJoachim Jenke #pragma omp atomic
293*6ef16f26SJoachim Jenke         --checker;
294*6ef16f26SJoachim Jenke       }
295*6ef16f26SJoachim Jenke       // compiler codegen start
296*6ef16f26SJoachim Jenke       // task6
297*6ef16f26SJoachim Jenke       ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
298*6ef16f26SJoachim Jenke       sdep[0].addr = (size_t)(-1); // omp_all_memory
299*6ef16f26SJoachim Jenke       sdep[0].len = 0; // not used
300*6ef16f26SJoachim Jenke       sdep[0].flags = 2; // OUT
301*6ef16f26SJoachim Jenke       ptr->f_priv = t + 30; // init single first-private variable
302*6ef16f26SJoachim Jenke       __kmpc_omp_task_with_deps(&loc, gtid, ptr, 1, sdep, 0, 0);
303*6ef16f26SJoachim Jenke 
304*6ef16f26SJoachim Jenke       // task7
305*6ef16f26SJoachim Jenke       ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
306*6ef16f26SJoachim Jenke       sdep[0].addr = 0;
307*6ef16f26SJoachim Jenke       sdep[0].len = 0; // not used
308*6ef16f26SJoachim Jenke       sdep[0].flags = DEP_ALL_MEM; // omp_all_memory
309*6ef16f26SJoachim Jenke       sdep[1].addr = (size_t)&i3; // to be ignored
310*6ef16f26SJoachim Jenke       sdep[1].len = 0; // not used
311*6ef16f26SJoachim Jenke       sdep[1].flags = 4; // MUTEXINOUTSET
312*6ef16f26SJoachim Jenke       ptr->f_priv = t + 40; // init single first-private variable
313*6ef16f26SJoachim Jenke       __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
314*6ef16f26SJoachim Jenke       // compiler codegen end
315*6ef16f26SJoachim Jenke #pragma omp task depend(in : i3)
316*6ef16f26SJoachim Jenke       { // task 8
317*6ef16f26SJoachim Jenke         int lcheck, th;
318*6ef16f26SJoachim Jenke #pragma omp atomic capture
319*6ef16f26SJoachim Jenke         lcheck = ++checker; // 1
320*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
321*6ef16f26SJoachim Jenke         printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);
322*6ef16f26SJoachim Jenke         if (lcheck != 1) {
323*6ef16f26SJoachim Jenke           err++;
324*6ef16f26SJoachim Jenke           printf("Error9, checker %d, != 1\n", lcheck);
325*6ef16f26SJoachim Jenke         }
326*6ef16f26SJoachim Jenke         mysleep(DELAY);
327*6ef16f26SJoachim Jenke #pragma omp atomic read
328*6ef16f26SJoachim Jenke         lcheck = checker;
329*6ef16f26SJoachim Jenke         if (lcheck != 1) {
330*6ef16f26SJoachim Jenke           err++;
331*6ef16f26SJoachim Jenke           printf("Error10, checker %d, != 1\n", lcheck);
332*6ef16f26SJoachim Jenke         }
333*6ef16f26SJoachim Jenke #pragma omp atomic
334*6ef16f26SJoachim Jenke         --checker;
335*6ef16f26SJoachim Jenke       }
336*6ef16f26SJoachim Jenke     } // single
337*6ef16f26SJoachim Jenke   } // parallel
338*6ef16f26SJoachim Jenke   if (err == 0 && checker == 0) {
339*6ef16f26SJoachim Jenke     printf("passed\n");
340*6ef16f26SJoachim Jenke     return 0;
341*6ef16f26SJoachim Jenke   } else {
342*6ef16f26SJoachim Jenke     printf("failed, err = %d, checker = %d\n", err, checker);
343*6ef16f26SJoachim Jenke     return 1;
344*6ef16f26SJoachim Jenke   }
345*6ef16f26SJoachim Jenke }
346