1// REQUIRES: linux
2// RUN: %libomp-compile && env OMP_NUM_THREADS='2' %libomp-run
3
4#include <assert.h>
5#include <omp.h>
6
7#include "kmp_task_deps.h"
8
9// the test
10int main(void) {
11 volatile int done = 0;
12
13#pragma omp parallel num_threads(2)
14 {
15 while (omp_get_thread_num() != 0 && !done)
16 ;
17
18#pragma omp single
19 {
20 kmp_task_t *A, *B;
21 kmp_depnode_list_t *A_succ;
22 kmp_base_depnode_t *B_node;
23 dep deps[2];
24 int gtid;
25 int x, y;
26
27 gtid = __kmpc_global_thread_num(&loc);
28
29 // A - out(x, y)
30 A = __kmpc_omp_task_alloc(loc: &loc, gtid, TIED, sz: sizeof(kmp_task_t), shar: 0, NULL);
31 deps[0].addr = (size_t)&x;
32 deps[0].len = 0;
33 deps[0].flags = 2; // OUT
34
35 deps[1].addr = (size_t)&y;
36 deps[1].len = 0;
37 deps[1].flags = 2; // OUT
38
39 __kmpc_omp_task_with_deps(loc: &loc, gtid, task: A, nd: 2, dep_lst: deps, nd_noalias: 0, noalias_dep_lst: 0);
40
41 // B - in(x, y)
42 B = __kmpc_omp_task_alloc(loc: &loc, gtid, TIED, sz: sizeof(kmp_task_t), shar: 0, NULL);
43 deps[0].addr = (size_t)&x;
44 deps[0].len = 0;
45 deps[0].flags = 1; // IN
46
47 deps[1].addr = (size_t)&y;
48 deps[1].len = 0;
49 deps[1].flags = 1; // IN
50
51 __kmpc_omp_task_with_deps(loc: &loc, gtid, task: B, nd: 2, dep_lst: deps, nd_noalias: 0, noalias_dep_lst: 0);
52
53 // Retrieve TDG nodes
54 A_succ = __kmpc_task_get_successors(task: A);
55 B_node = __kmpc_task_get_depnode(task: B);
56
57 // 'B' should only be added once to 'A' successors list
58 assert(A_succ->node == B_node);
59 assert(A_succ->next == NULL);
60
61#pragma omp taskwait
62
63 done = 1;
64 }
65 }
66 return 0;
67}
68

source code of openmp/runtime/test/tasking/kmp_task_deps_multiple_edges.c