1 // RUN: %libomp-compile-and-run
2 // The runtime currently does not get dependency information from GCC.
5 // Very flaky on openmp-clang-x86_64-linux-debian.
6 // https://bugs.llvm.org/show_bug.cgi?id=45397
12 #include "omp_testsuite.h"
13 #include "omp_my_sleep.h"
16 An explicit task can have a dependency on a target task. If it is not
17 directly satisfied, the runtime should not wait but resume execution.
20 // Compiler-generated code (emulation)
21 typedef intptr_t kmp_intptr_t
;
22 typedef int32_t kmp_int32
;
23 typedef uint8_t kmp_uint8
;
27 // These structs need to match the implementation within libomp, in kmp.h.
29 typedef struct ident
{
30 kmp_int32 reserved_1
; /**< might be used in Fortran; see above */
31 kmp_int32 flags
; /**< also f.flags; KMP_IDENT_xxx flags; KMP_IDENT_KMPC identifies this union member */
32 kmp_int32 reserved_2
; /**< not really used in Fortran any more; see above */
34 /* but currently used for storing region-specific ITT */
35 /* contextual information. */
36 #endif /* USE_ITT_BUILD */
37 kmp_int32 reserved_3
; /**< source[4] in Fortran, do not use for C++ */
38 char const *psource
; /**< String describing the source location.
39 The string is composed of semi-colon separated fields which describe the source file,
40 the function and a pair of line numbers that delimit the construct.
44 typedef struct kmp_depend_info
{
45 kmp_intptr_t base_addr
;
48 kmp_uint8 flag
; // flag as an unsigned char
49 struct { // flag as a set of 8 bits
61 typedef kmp_int32 (* kmp_routine_entry_t
)( kmp_int32
, struct kmp_task
* );
63 typedef struct kmp_task
{ /* GEH: Shouldn't this be aligned somehow? */
64 void * shareds
; /**< pointer to block of pointers to shared vars */
65 kmp_routine_entry_t routine
; /**< pointer to routine to call for executing task */
66 kmp_int32 part_id
; /**< part id for the task */
72 kmp_int32
__kmpc_global_thread_num ( ident_t
* );
74 __kmpc_omp_task_alloc( ident_t
*loc_ref
, kmp_int32 gtid
, kmp_int32 flags
,
75 size_t sizeof_kmp_task_t
, size_t sizeof_shareds
,
76 kmp_routine_entry_t task_entry
);
77 void __kmpc_proxy_task_completed_ooo ( kmp_task_t
*ptask
);
78 kmp_int32
__kmpc_omp_task_with_deps ( ident_t
*loc_ref
, kmp_int32 gtid
, kmp_task_t
* new_task
,
79 kmp_int32 ndeps
, kmp_depend_info_t
*dep_list
,
80 kmp_int32 ndeps_noalias
, kmp_depend_info_t
*noalias_dep_list
);
82 __kmpc_omp_task( ident_t
*loc_ref
, kmp_int32 gtid
, kmp_task_t
* new_task
);
87 void *target(void *task
)
90 __kmpc_proxy_task_completed_ooo((kmp_task_t
*) task
);
94 pthread_t target_thread
;
97 int task_entry(kmp_int32 gtid
, kmp_task_t
*task
)
99 pthread_create(&target_thread
, NULL
, &target
, task
);
109 #pragma omp target nowait depend(out: dep)
114 kmp_depend_info_t dep_info
= { 0 };
115 dep_info
.base_addr
= (kmp_intptr_t
) &dep
;
116 dep_info
.len
= sizeof(int);
117 // out = inout per spec and runtime expects this
118 dep_info
.flags
.in
= 1;
119 dep_info
.flags
.out
= 1;
121 kmp_int32 gtid
= __kmpc_global_thread_num(NULL
);
122 kmp_task_t
*proxy_task
= __kmpc_omp_task_alloc(NULL
,gtid
,17,sizeof(kmp_task_t
),0,&task_entry
);
123 __kmpc_omp_task_with_deps(NULL
,gtid
,proxy_task
,1,&dep_info
,0,NULL
);
125 int first_task_finished
= 0;
126 #pragma omp task shared(first_task_finished) depend(inout: dep)
128 first_task_finished
= 1;
131 int second_task_finished
= 0;
132 #pragma omp task shared(second_task_finished) depend(in: dep)
134 second_task_finished
= 1;
137 // check that execution has been resumed and the runtime has not waited
138 // for the dependencies to be satisfied.
139 int error
= (first_task_finished
== 1);
140 error
+= (second_task_finished
== 1);
144 // by now all tasks should have finished
145 error
+= (first_task_finished
!= 1);
146 error
+= (second_task_finished
!= 1);