xref: /llvm-project/openmp/runtime/test/ompt/tasks/omp_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 // The runtime currently does not get dependency information from GCC.
5*6ef16f26SJoachim Jenke // UNSUPPORTED: gcc
6*6ef16f26SJoachim Jenke 
7*6ef16f26SJoachim Jenke // Tests OMP 5.x task dependence "omp_all_memory",
8*6ef16f26SJoachim Jenke // emulates compiler codegen versions for new dep kind
9*6ef16f26SJoachim Jenke //
10*6ef16f26SJoachim Jenke // Task tree created:
11*6ef16f26SJoachim Jenke //      task0 - task1 (in: i1, i2)
12*6ef16f26SJoachim Jenke //             \
13*6ef16f26SJoachim Jenke //        task2 (inoutset: i2), (in: i1)
14*6ef16f26SJoachim Jenke //             /
15*6ef16f26SJoachim Jenke //        task3 (omp_all_memory) via flag=0x80
16*6ef16f26SJoachim Jenke //             /
17*6ef16f26SJoachim Jenke //      task4 - task5 (in: i1, i2)
18*6ef16f26SJoachim Jenke //           /
19*6ef16f26SJoachim Jenke //       task6 (omp_all_memory) via addr=-1
20*6ef16f26SJoachim Jenke //           /
21*6ef16f26SJoachim Jenke //       task7 (omp_all_memory) via flag=0x80
22*6ef16f26SJoachim Jenke //           /
23*6ef16f26SJoachim Jenke //       task8 (in: i3)
24*6ef16f26SJoachim Jenke //
25*6ef16f26SJoachim Jenke 
26*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
27*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
28*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
29*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
30*6ef16f26SJoachim Jenke 
31*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
32*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
33*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
34*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
35*6ef16f26SJoachim Jenke 
36*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
37*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
38*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_inoutset
39*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
40*6ef16f26SJoachim Jenke 
41*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
42*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
43*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_out_all_memory
44*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
45*6ef16f26SJoachim Jenke 
46*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
47*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
48*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
49*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
50*6ef16f26SJoachim Jenke 
51*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
52*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
53*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
54*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
55*6ef16f26SJoachim Jenke 
56*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
57*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_out_all_memory
58*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=1
59*6ef16f26SJoachim Jenke 
60*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
61*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_out_all_memory
62*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_mutexinoutset
63*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=2
64*6ef16f26SJoachim Jenke 
65*6ef16f26SJoachim Jenke // CHECK: ompt_event_dependences:
66*6ef16f26SJoachim Jenke // CHECK-SAME: ompt_dependence_type_in
67*6ef16f26SJoachim Jenke // CHECK-SAME: ndeps=1
68*6ef16f26SJoachim Jenke 
69*6ef16f26SJoachim Jenke #include "callback.h"
70*6ef16f26SJoachim Jenke #include <stdio.h>
71*6ef16f26SJoachim Jenke #include <omp.h>
72*6ef16f26SJoachim Jenke 
73*6ef16f26SJoachim Jenke #ifdef _WIN32
74*6ef16f26SJoachim Jenke #include <windows.h>
75*6ef16f26SJoachim Jenke #define mysleep(n) Sleep(n)
76*6ef16f26SJoachim Jenke #else
77*6ef16f26SJoachim Jenke #include <unistd.h>
78*6ef16f26SJoachim Jenke #define mysleep(n) usleep((n)*1000)
79*6ef16f26SJoachim Jenke #endif
80*6ef16f26SJoachim Jenke 
81*6ef16f26SJoachim Jenke // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
82*6ef16f26SJoachim Jenke static int checker = 0;
83*6ef16f26SJoachim Jenke static int err = 0;
84*6ef16f26SJoachim Jenke #ifndef DELAY
85*6ef16f26SJoachim Jenke #define DELAY 100
86*6ef16f26SJoachim Jenke #endif
87*6ef16f26SJoachim Jenke 
88*6ef16f26SJoachim Jenke // ---------------------------------------------------------------------------
89*6ef16f26SJoachim Jenke // internal data to emulate compiler codegen
90*6ef16f26SJoachim Jenke typedef struct DEP {
91*6ef16f26SJoachim Jenke   size_t addr;
92*6ef16f26SJoachim Jenke   size_t len;
93*6ef16f26SJoachim Jenke   unsigned char flags;
94*6ef16f26SJoachim Jenke } dep;
95*6ef16f26SJoachim Jenke #define DEP_ALL_MEM 0x80
96*6ef16f26SJoachim Jenke typedef struct task {
97*6ef16f26SJoachim Jenke   void **shareds;
98*6ef16f26SJoachim Jenke   void *entry;
99*6ef16f26SJoachim Jenke   int part_id;
100*6ef16f26SJoachim Jenke   void *destr_thunk;
101*6ef16f26SJoachim Jenke   int priority;
102*6ef16f26SJoachim Jenke   long long device_id;
103*6ef16f26SJoachim Jenke   int f_priv;
104*6ef16f26SJoachim Jenke } task_t;
105*6ef16f26SJoachim Jenke #define TIED 1
106*6ef16f26SJoachim Jenke typedef int (*entry_t)(int, task_t *);
107*6ef16f26SJoachim Jenke typedef struct ID {
108*6ef16f26SJoachim Jenke   int reserved_1;
109*6ef16f26SJoachim Jenke   int flags;
110*6ef16f26SJoachim Jenke   int reserved_2;
111*6ef16f26SJoachim Jenke   int reserved_3;
112*6ef16f26SJoachim Jenke   char *psource;
113*6ef16f26SJoachim Jenke } id;
114*6ef16f26SJoachim Jenke // thunk routine for tasks with ALL dependency
thunk_m(int gtid,task_t * ptask)115*6ef16f26SJoachim Jenke int thunk_m(int gtid, task_t *ptask) {
116*6ef16f26SJoachim Jenke   int lcheck, th;
117*6ef16f26SJoachim Jenke #pragma omp atomic capture
118*6ef16f26SJoachim Jenke   lcheck = ++checker;
119*6ef16f26SJoachim Jenke   th = omp_get_thread_num();
120*6ef16f26SJoachim Jenke   printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
121*6ef16f26SJoachim Jenke   if (lcheck != 1) { // no more than 1 task at a time
122*6ef16f26SJoachim Jenke     err++;
123*6ef16f26SJoachim Jenke     printf("Error m1, checker %d != 1\n", lcheck);
124*6ef16f26SJoachim Jenke   }
125*6ef16f26SJoachim Jenke   mysleep(DELAY);
126*6ef16f26SJoachim Jenke #pragma omp atomic read
127*6ef16f26SJoachim Jenke   lcheck = checker; // must still be equal to 1
128*6ef16f26SJoachim Jenke   if (lcheck != 1) {
129*6ef16f26SJoachim Jenke     err++;
130*6ef16f26SJoachim Jenke     printf("Error m2, checker %d != 1\n", lcheck);
131*6ef16f26SJoachim Jenke   }
132*6ef16f26SJoachim Jenke #pragma omp atomic
133*6ef16f26SJoachim Jenke   --checker;
134*6ef16f26SJoachim Jenke   return 0;
135*6ef16f26SJoachim Jenke }
136*6ef16f26SJoachim Jenke // thunk routine for tasks with inoutset dependency
thunk_s(int gtid,task_t * ptask)137*6ef16f26SJoachim Jenke int thunk_s(int gtid, task_t *ptask) {
138*6ef16f26SJoachim Jenke   int lcheck, th;
139*6ef16f26SJoachim Jenke #pragma omp atomic capture
140*6ef16f26SJoachim Jenke   lcheck = ++checker; // 1
141*6ef16f26SJoachim Jenke   th = omp_get_thread_num();
142*6ef16f26SJoachim Jenke   printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
143*6ef16f26SJoachim Jenke   if (lcheck != 1) { // no more than 1 task at a time
144*6ef16f26SJoachim Jenke     err++;
145*6ef16f26SJoachim Jenke     printf("Error s1, checker %d != 1\n", lcheck);
146*6ef16f26SJoachim Jenke   }
147*6ef16f26SJoachim Jenke   mysleep(DELAY);
148*6ef16f26SJoachim Jenke #pragma omp atomic read
149*6ef16f26SJoachim Jenke   lcheck = checker; // must still be equal to 1
150*6ef16f26SJoachim Jenke   if (lcheck != 1) {
151*6ef16f26SJoachim Jenke     err++;
152*6ef16f26SJoachim Jenke     printf("Error s2, checker %d != 1\n", lcheck);
153*6ef16f26SJoachim Jenke   }
154*6ef16f26SJoachim Jenke #pragma omp atomic
155*6ef16f26SJoachim Jenke   --checker;
156*6ef16f26SJoachim Jenke   return 0;
157*6ef16f26SJoachim Jenke }
158*6ef16f26SJoachim Jenke 
159*6ef16f26SJoachim Jenke #ifdef __cplusplus
160*6ef16f26SJoachim Jenke extern "C" {
161*6ef16f26SJoachim Jenke #endif
162*6ef16f26SJoachim Jenke int __kmpc_global_thread_num(id *);
163*6ef16f26SJoachim Jenke task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,
164*6ef16f26SJoachim Jenke                               size_t shar, entry_t rtn);
165*6ef16f26SJoachim Jenke int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,
166*6ef16f26SJoachim Jenke                               dep *dep_lst, int nd_noalias, dep *noalias_lst);
167*6ef16f26SJoachim Jenke static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};
168*6ef16f26SJoachim Jenke #ifdef __cplusplus
169*6ef16f26SJoachim Jenke } // extern "C"
170*6ef16f26SJoachim Jenke #endif
171*6ef16f26SJoachim Jenke // End of internal data
172*6ef16f26SJoachim Jenke // ---------------------------------------------------------------------------
173*6ef16f26SJoachim Jenke 
main()174*6ef16f26SJoachim Jenke int main() {
175*6ef16f26SJoachim Jenke   char *ompx_all_memory = (void *)0xffffffffffffffff;
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 #pragma omp task depend(in : i1) depend(inout : ompx_all_memory[0])
244*6ef16f26SJoachim Jenke       {
245*6ef16f26SJoachim Jenke         int lcheck, th;
246*6ef16f26SJoachim Jenke #pragma omp atomic capture
247*6ef16f26SJoachim Jenke         lcheck = ++checker;
248*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
249*6ef16f26SJoachim Jenke         printf("task m_%d, th %d, checker %d\n", t, th, lcheck);
250*6ef16f26SJoachim Jenke         if (lcheck != 1) { // no more than 1 task at a time
251*6ef16f26SJoachim Jenke           err++;
252*6ef16f26SJoachim Jenke           printf("Error m1, checker %d != 1\n", lcheck);
253*6ef16f26SJoachim Jenke         }
254*6ef16f26SJoachim Jenke         mysleep(DELAY);
255*6ef16f26SJoachim Jenke #pragma omp atomic read
256*6ef16f26SJoachim Jenke         lcheck = checker; // must still be equal to 1
257*6ef16f26SJoachim Jenke         if (lcheck != 1) {
258*6ef16f26SJoachim Jenke           err++;
259*6ef16f26SJoachim Jenke           printf("Error m2, checker %d != 1\n", lcheck);
260*6ef16f26SJoachim Jenke         }
261*6ef16f26SJoachim Jenke #pragma omp atomic
262*6ef16f26SJoachim Jenke         --checker;
263*6ef16f26SJoachim Jenke       }
264*6ef16f26SJoachim Jenke       // compiler codegen end
265*6ef16f26SJoachim Jenke #pragma omp task depend(in : i1, i2)
266*6ef16f26SJoachim Jenke       { // task 4
267*6ef16f26SJoachim Jenke         int lcheck, th;
268*6ef16f26SJoachim Jenke #pragma omp atomic capture
269*6ef16f26SJoachim Jenke         lcheck = ++checker; // 1 or 2
270*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
271*6ef16f26SJoachim Jenke         printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);
272*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
273*6ef16f26SJoachim Jenke           err++; // no more than 2 tasks concurrently
274*6ef16f26SJoachim Jenke           printf("Error5, checker %d, not 1 or 2\n", lcheck);
275*6ef16f26SJoachim Jenke         }
276*6ef16f26SJoachim Jenke         mysleep(DELAY);
277*6ef16f26SJoachim Jenke #pragma omp atomic read
278*6ef16f26SJoachim Jenke         lcheck = checker; // 1 or 2
279*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
280*6ef16f26SJoachim Jenke           err++;
281*6ef16f26SJoachim Jenke           printf("Error6, checker %d, not 1 or 2\n", lcheck);
282*6ef16f26SJoachim Jenke         }
283*6ef16f26SJoachim Jenke #pragma omp atomic
284*6ef16f26SJoachim Jenke         --checker;
285*6ef16f26SJoachim Jenke       }
286*6ef16f26SJoachim Jenke #pragma omp task depend(in : i1, i2)
287*6ef16f26SJoachim Jenke       { // task 5
288*6ef16f26SJoachim Jenke         int lcheck, th;
289*6ef16f26SJoachim Jenke #pragma omp atomic capture
290*6ef16f26SJoachim Jenke         lcheck = ++checker; // 1 or 2
291*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
292*6ef16f26SJoachim Jenke         printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);
293*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
294*6ef16f26SJoachim Jenke           err++; // no more than 2 tasks concurrently
295*6ef16f26SJoachim Jenke           printf("Error7, checker %d, not 1 or 2\n", lcheck);
296*6ef16f26SJoachim Jenke         }
297*6ef16f26SJoachim Jenke         mysleep(DELAY);
298*6ef16f26SJoachim Jenke #pragma omp atomic read
299*6ef16f26SJoachim Jenke         lcheck = checker; // 1 or 2
300*6ef16f26SJoachim Jenke         if (lcheck > 2 || lcheck < 1) {
301*6ef16f26SJoachim Jenke           err++;
302*6ef16f26SJoachim Jenke           printf("Error8, checker %d, not 1 or 2\n", lcheck);
303*6ef16f26SJoachim Jenke         }
304*6ef16f26SJoachim Jenke #pragma omp atomic
305*6ef16f26SJoachim Jenke         --checker;
306*6ef16f26SJoachim Jenke       }
307*6ef16f26SJoachim Jenke // task6
308*6ef16f26SJoachim Jenke #pragma omp task depend(inout : ompx_all_memory[0])
309*6ef16f26SJoachim Jenke       {
310*6ef16f26SJoachim Jenke         int lcheck, th;
311*6ef16f26SJoachim Jenke #pragma omp atomic capture
312*6ef16f26SJoachim Jenke         lcheck = ++checker;
313*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
314*6ef16f26SJoachim Jenke         printf("task m_%d, th %d, checker %d\n", t, th, lcheck);
315*6ef16f26SJoachim Jenke         if (lcheck != 1) { // no more than 1 task at a time
316*6ef16f26SJoachim Jenke           err++;
317*6ef16f26SJoachim Jenke           printf("Error m1, checker %d != 1\n", lcheck);
318*6ef16f26SJoachim Jenke         }
319*6ef16f26SJoachim Jenke         mysleep(DELAY);
320*6ef16f26SJoachim Jenke #pragma omp atomic read
321*6ef16f26SJoachim Jenke         lcheck = checker; // must still be equal to 1
322*6ef16f26SJoachim Jenke         if (lcheck != 1) {
323*6ef16f26SJoachim Jenke           err++;
324*6ef16f26SJoachim Jenke           printf("Error m2, checker %d != 1\n", lcheck);
325*6ef16f26SJoachim Jenke         }
326*6ef16f26SJoachim Jenke #pragma omp atomic
327*6ef16f26SJoachim Jenke         --checker;
328*6ef16f26SJoachim Jenke       }
329*6ef16f26SJoachim Jenke // task7
330*6ef16f26SJoachim Jenke #pragma omp task depend(inout : ompx_all_memory[0]) depend(mutexinoutset : i3)
331*6ef16f26SJoachim Jenke       {
332*6ef16f26SJoachim Jenke         int lcheck, th;
333*6ef16f26SJoachim Jenke #pragma omp atomic capture
334*6ef16f26SJoachim Jenke         lcheck = ++checker;
335*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
336*6ef16f26SJoachim Jenke         printf("task m_%d, th %d, checker %d\n", t, th, lcheck);
337*6ef16f26SJoachim Jenke         if (lcheck != 1) { // no more than 1 task at a time
338*6ef16f26SJoachim Jenke           err++;
339*6ef16f26SJoachim Jenke           printf("Error m1, checker %d != 1\n", lcheck);
340*6ef16f26SJoachim Jenke         }
341*6ef16f26SJoachim Jenke         mysleep(DELAY);
342*6ef16f26SJoachim Jenke #pragma omp atomic read
343*6ef16f26SJoachim Jenke         lcheck = checker; // must still be equal to 1
344*6ef16f26SJoachim Jenke         if (lcheck != 1) {
345*6ef16f26SJoachim Jenke           err++;
346*6ef16f26SJoachim Jenke           printf("Error m2, checker %d != 1\n", lcheck);
347*6ef16f26SJoachim Jenke         }
348*6ef16f26SJoachim Jenke #pragma omp atomic
349*6ef16f26SJoachim Jenke         --checker;
350*6ef16f26SJoachim Jenke       }
351*6ef16f26SJoachim Jenke #pragma omp task depend(in : i3)
352*6ef16f26SJoachim Jenke       { // task 8
353*6ef16f26SJoachim Jenke         int lcheck, th;
354*6ef16f26SJoachim Jenke #pragma omp atomic capture
355*6ef16f26SJoachim Jenke         lcheck = ++checker; // 1
356*6ef16f26SJoachim Jenke         th = omp_get_thread_num();
357*6ef16f26SJoachim Jenke         printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);
358*6ef16f26SJoachim Jenke         if (lcheck != 1) {
359*6ef16f26SJoachim Jenke           err++;
360*6ef16f26SJoachim Jenke           printf("Error9, checker %d, != 1\n", lcheck);
361*6ef16f26SJoachim Jenke         }
362*6ef16f26SJoachim Jenke         mysleep(DELAY);
363*6ef16f26SJoachim Jenke #pragma omp atomic read
364*6ef16f26SJoachim Jenke         lcheck = checker;
365*6ef16f26SJoachim Jenke         if (lcheck != 1) {
366*6ef16f26SJoachim Jenke           err++;
367*6ef16f26SJoachim Jenke           printf("Error10, checker %d, != 1\n", lcheck);
368*6ef16f26SJoachim Jenke         }
369*6ef16f26SJoachim Jenke #pragma omp atomic
370*6ef16f26SJoachim Jenke         --checker;
371*6ef16f26SJoachim Jenke       }
372*6ef16f26SJoachim Jenke     } // single
373*6ef16f26SJoachim Jenke   } // parallel
374*6ef16f26SJoachim Jenke   if (err == 0 && checker == 0) {
375*6ef16f26SJoachim Jenke     printf("passed\n");
376*6ef16f26SJoachim Jenke     return 0;
377*6ef16f26SJoachim Jenke   } else {
378*6ef16f26SJoachim Jenke     printf("failed, err = %d, checker = %d\n", err, checker);
379*6ef16f26SJoachim Jenke     return 1;
380*6ef16f26SJoachim Jenke   }
381*6ef16f26SJoachim Jenke }
382