1 // RUN--: %libarcher-compile-and-run | FileCheck %s --check-prefix=NOENV
2 // RUN: %libarcher-compile && env ARCHER_OPTIONS="all_memory=1" \
3 // RUN: %libarcher-run | FileCheck %s --check-prefix=ENV
6 // The runtime currently does not get dependency information from GCC.
9 // Tests OMP 5.x task dependence "omp_all_memory",
10 // emulates compiler codegen versions for new dep kind
13 // task0 - task1 (in: i1, i2)
15 // task2 (inoutset: i2), (in: i1)
17 // task3 (omp_all_memory) via flag=0x80
19 // task4 - task5 (in: i1, i2)
21 // task6 (omp_all_memory) via addr=-1
23 // task7 (omp_all_memory) via flag=0x80
33 #define mysleep(n) Sleep(n)
36 #define mysleep(n) usleep((n)*1000)
39 // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
40 static int checker
= 0;
46 // ---------------------------------------------------------------------------
47 // internal data to emulate compiler codegen
53 #define DEP_ALL_MEM 0x80
64 typedef int (*entry_t
)(int, task_t
*);
72 // thunk routine for tasks with ALL dependency
73 int thunk_m(int gtid
, task_t
*ptask
) {
75 #pragma omp atomic capture
77 th
= omp_get_thread_num();
78 printf("task m_%d, th %d, checker %d\n", ptask
->f_priv
, th
, lcheck
);
79 if (lcheck
!= 1) { // no more than 1 task at a time
81 printf("Error m1, checker %d != 1\n", lcheck
);
84 #pragma omp atomic read
85 lcheck
= checker
; // must still be equal to 1
88 printf("Error m2, checker %d != 1\n", lcheck
);
94 // thunk routine for tasks with inoutset dependency
95 int thunk_s(int gtid
, task_t
*ptask
) {
97 #pragma omp atomic capture
98 lcheck
= ++checker
; // 1
99 th
= omp_get_thread_num();
100 printf("task 2_%d, th %d, checker %d\n", ptask
->f_priv
, th
, lcheck
);
101 if (lcheck
!= 1) { // no more than 1 task at a time
103 printf("Error s1, checker %d != 1\n", lcheck
);
106 #pragma omp atomic read
107 lcheck
= checker
; // must still be equal to 1
110 printf("Error s2, checker %d != 1\n", lcheck
);
120 int __kmpc_global_thread_num(id
*);
121 task_t
*__kmpc_omp_task_alloc(id
*loc
, int gtid
, int flags
, size_t sz
,
122 size_t shar
, entry_t rtn
);
123 int __kmpc_omp_task_with_deps(id
*loc
, int gtid
, task_t
*task
, int ndeps
,
124 dep
*dep_lst
, int nd_noalias
, dep
*noalias_lst
);
125 static id loc
= {0, 2, 0, 0, ";file;func;0;0;;"};
129 // End of internal data
130 // ---------------------------------------------------------------------------
133 char *ompx_all_memory
= (void *)0xffffffffffffffff;
135 omp_set_num_threads(8);
139 #pragma omp single nowait
143 int gtid
= __kmpc_global_thread_num(&loc
);
144 int t
= omp_get_thread_num();
145 #pragma omp task depend(in : i1, i2)
148 #pragma omp atomic capture
149 lcheck
= ++checker
; // 1 or 2
150 th
= omp_get_thread_num();
151 printf("task 0_%d, th %d, checker %d\n", t
, th
, lcheck
);
152 if (lcheck
> 2 || lcheck
< 1) {
153 err
++; // no more than 2 tasks concurrently
154 printf("Error1, checker %d, not 1 or 2\n", lcheck
);
157 #pragma omp atomic read
158 lcheck
= checker
; // 1 or 2
159 if (lcheck
> 2 || lcheck
< 1) {
162 printf("Error2, checker %d, not 1 or 2\n", lcheck
);
167 #pragma omp task depend(in : i1, i2)
170 #pragma omp atomic capture
171 lcheck
= ++checker
; // 1 or 2
172 th
= omp_get_thread_num();
173 printf("task 1_%d, th %d, checker %d\n", t
, th
, lcheck
);
174 if (lcheck
> 2 || lcheck
< 1) {
175 err
++; // no more than 2 tasks concurrently
176 printf("Error3, checker %d, not 1 or 2\n", lcheck
);
179 #pragma omp atomic read
180 lcheck
= checker
; // 1 or 2
181 if (lcheck
> 2 || lcheck
< 1) {
183 printf("Error4, checker %d, not 1 or 2\n", lcheck
);
188 // compiler codegen start
190 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_s
);
191 sdep
[0].addr
= (size_t)&i1
;
192 sdep
[0].len
= 0; // not used
193 sdep
[0].flags
= 1; // IN
194 sdep
[1].addr
= (size_t)&i2
;
195 sdep
[1].len
= 0; // not used
196 sdep
[1].flags
= 8; // INOUTSET
197 ptr
->f_priv
= t
+ 10; // init single first-private variable
198 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
201 #pragma omp task depend(in : i1) depend(inout : ompx_all_memory[0])
204 #pragma omp atomic capture
206 th
= omp_get_thread_num();
207 printf("task 3_%d, th %d, checker %d\n", t
, th
, lcheck
);
208 if (lcheck
!= 1) { // no more than 1 task at a time
210 printf("Error m1, checker %d != 1\n", lcheck
);
213 #pragma omp atomic read
214 lcheck
= checker
; // must still be equal to 1
217 printf("Error m2, checker %d != 1\n", lcheck
);
222 // compiler codegen end
223 #pragma omp task depend(in : i1, i2)
226 #pragma omp atomic capture
227 lcheck
= ++checker
; // 1 or 2
228 th
= omp_get_thread_num();
229 printf("task 4_%d, th %d, checker %d\n", t
, th
, lcheck
);
230 if (lcheck
> 2 || lcheck
< 1) {
231 err
++; // no more than 2 tasks concurrently
232 printf("Error5, checker %d, not 1 or 2\n", lcheck
);
235 #pragma omp atomic read
236 lcheck
= checker
; // 1 or 2
237 if (lcheck
> 2 || lcheck
< 1) {
239 printf("Error6, checker %d, not 1 or 2\n", lcheck
);
244 #pragma omp task depend(in : i1, i2)
247 #pragma omp atomic capture
248 lcheck
= ++checker
; // 1 or 2
249 th
= omp_get_thread_num();
250 printf("task 5_%d, th %d, checker %d\n", t
, th
, lcheck
);
251 if (lcheck
> 2 || lcheck
< 1) {
252 err
++; // no more than 2 tasks concurrently
253 printf("Error7, checker %d, not 1 or 2\n", lcheck
);
256 #pragma omp atomic read
257 lcheck
= checker
; // 1 or 2
258 if (lcheck
> 2 || lcheck
< 1) {
260 printf("Error8, checker %d, not 1 or 2\n", lcheck
);
266 #pragma omp task depend(inout : ompx_all_memory[0])
269 #pragma omp atomic capture
271 th
= omp_get_thread_num();
272 printf("task 6_%d, th %d, checker %d\n", t
, th
, lcheck
);
273 if (lcheck
!= 1) { // no more than 1 task at a time
275 printf("Error m1, checker %d != 1\n", lcheck
);
278 #pragma omp atomic read
279 lcheck
= checker
; // must still be equal to 1
282 printf("Error m2, checker %d != 1\n", lcheck
);
288 #pragma omp task depend(inout : ompx_all_memory[0]) depend(mutexinoutset : i3)
291 #pragma omp atomic capture
293 th
= omp_get_thread_num();
294 printf("task 7_%d, th %d, checker %d\n", t
, th
, lcheck
);
295 if (lcheck
!= 1) { // no more than 1 task at a time
297 printf("Error m1, checker %d != 1\n", lcheck
);
300 #pragma omp atomic read
301 lcheck
= checker
; // must still be equal to 1
304 printf("Error m2, checker %d != 1\n", lcheck
);
309 #pragma omp task depend(in : i3)
312 #pragma omp atomic capture
313 lcheck
= ++checker
; // 1
314 th
= omp_get_thread_num();
315 printf("task 8_%d, th %d, checker %d\n", t
, th
, lcheck
);
318 printf("Error9, checker %d, != 1\n", lcheck
);
321 #pragma omp atomic read
325 printf("Error10, checker %d, != 1\n", lcheck
);
332 if (err
== 0 && checker
== 0) {
336 printf("failed, err = %d, checker = %d\n", err
, checker
);
341 // NOENV-NOT: ThreadSanitizer: data race
342 // NOENV-NOT: ThreadSanitizer: reported
343 // NOENV: omp_all_memory
344 // NOENV-NOT: ThreadSanitizer: data race
345 // NOENV-NOT: ThreadSanitizer: reported
348 // ENV-NOT: ThreadSanitizer: data race
349 // ENV-NOT: ThreadSanitizer: reported