LLVM OpenMP
omp_untied_task_if0.c
Go to the documentation of this file.
1// RUN: %libomp-compile-and-run
2
3// An untied task whose 'if' clause evaluates to false is executed immediately
4// via __kmpc_omp_task_begin_if0(), which makes it the thread's current task.
5// It must still inherit td_last_tied from the task it suspends, the way the
6// deferred path does in __kmp_invoke_task(). Otherwise it becomes the current
7// task with a NULL td_last_tied, and applying the task scheduling constraint
8// to any task scheduled from it (here, at the nested taskwait) either asserts
9// in __kmp_invoke_task() for an untied candidate, or dereferences NULL in
10// __kmp_task_is_allowed() for a tied candidate. See issue #172938.
11
12#include <stdio.h>
13#include <omp.h>
14
15#define REPS 50
16#define CHILDREN 16
17
18// Not a constant, so the 'if' clause is a runtime condition and the compiler
19// emits the __kmpc_omp_task_begin_if0() path for the false case.
20int cond = 0;
21
22int main(void) {
23 int counter = 0;
24
25 for (int r = 0; r < REPS; ++r) {
26#pragma omp parallel
27 {
28#pragma omp single
29 {
30#pragma omp task if (cond) untied
31 {
32 for (int i = 0; i < CHILDREN; ++i) {
33 // A tied child exercises __kmp_task_is_allowed(); an untied child
34 // exercises the inheritance in __kmp_invoke_task().
35 if (i % 2) {
36#pragma omp task
37 {
38#pragma omp atomic
39 counter++;
40 }
41 } else {
42#pragma omp task untied
43 {
44#pragma omp atomic
45 counter++;
46 }
47 }
48 }
49#pragma omp taskwait
50 }
51 }
52 }
53 }
54
55 if (counter != REPS * CHILDREN) {
56 fprintf(stderr, "failed: counter = %d, expected %d\n", counter,
57 REPS * CHILDREN);
58 return 1;
59 }
60 printf("passed\n");
61 return 0;
62}
#define i
Definition kmp_stub.cpp:88
int counter
#define REPS
int cond
#define CHILDREN
int main(void)