xref: /llvm-project/openmp/runtime/test/tasking/kmp_detach_tasks_t3.c (revision 77c2b623ca4ce10ec1019b31706a055aad2580cd)
1405037c4SAndrey Churbanov // RUN: %libomp-compile && env OMP_NUM_THREADS='3' %libomp-run
2405037c4SAndrey Churbanov // RUN: %libomp-compile && env OMP_NUM_THREADS='1' %libomp-run
3405037c4SAndrey Churbanov // The runtime currently does not get dependency information from GCC.
4405037c4SAndrey Churbanov // UNSUPPORTED: gcc
5405037c4SAndrey Churbanov 
6405037c4SAndrey Churbanov #include <stdio.h>
7405037c4SAndrey Churbanov #include <omp.h>
8405037c4SAndrey Churbanov #include "omp_my_sleep.h"
9405037c4SAndrey Churbanov 
10405037c4SAndrey Churbanov // detached untied
11405037c4SAndrey Churbanov #define PTASK_FLAG_DETACHABLE 0x40
12405037c4SAndrey Churbanov 
13405037c4SAndrey Churbanov // OpenMP RTL interfaces
14405037c4SAndrey Churbanov typedef unsigned long long kmp_uint64;
15405037c4SAndrey Churbanov typedef long long kmp_int64;
16405037c4SAndrey Churbanov 
17405037c4SAndrey Churbanov typedef struct ID {
18405037c4SAndrey Churbanov   int reserved_1;
19405037c4SAndrey Churbanov   int flags;
20405037c4SAndrey Churbanov   int reserved_2;
21405037c4SAndrey Churbanov   int reserved_3;
22405037c4SAndrey Churbanov   char *psource;
23405037c4SAndrey Churbanov } id;
24405037c4SAndrey Churbanov 
25405037c4SAndrey Churbanov // Compiler-generated code (emulation)
26405037c4SAndrey Churbanov typedef struct ident {
27405037c4SAndrey Churbanov   void* dummy; // not used in the library
28405037c4SAndrey Churbanov } ident_t;
29405037c4SAndrey Churbanov 
30405037c4SAndrey Churbanov typedef enum kmp_event_type_t {
31405037c4SAndrey Churbanov   KMP_EVENT_UNINITIALIZED = 0,
32405037c4SAndrey Churbanov   KMP_EVENT_ALLOW_COMPLETION = 1
33405037c4SAndrey Churbanov } kmp_event_type_t;
34405037c4SAndrey Churbanov 
35405037c4SAndrey Churbanov typedef struct {
36405037c4SAndrey Churbanov   kmp_event_type_t type;
37405037c4SAndrey Churbanov   union {
38405037c4SAndrey Churbanov     void *task;
39405037c4SAndrey Churbanov   } ed;
40405037c4SAndrey Churbanov } kmp_event_t;
41405037c4SAndrey Churbanov 
42405037c4SAndrey Churbanov typedef struct shar { // shareds used in the task
43405037c4SAndrey Churbanov } *pshareds;
44405037c4SAndrey Churbanov 
45405037c4SAndrey Churbanov typedef struct task {
46405037c4SAndrey Churbanov   pshareds shareds;
47405037c4SAndrey Churbanov   int(*routine)(int,struct task*);
48405037c4SAndrey Churbanov   int part_id;
49405037c4SAndrey Churbanov // void *destructor_thunk; // optional, needs flag setting if provided
50405037c4SAndrey Churbanov // int priority; // optional, needs flag setting if provided
51405037c4SAndrey Churbanov // ------------------------------
52405037c4SAndrey Churbanov // privates used in the task:
53405037c4SAndrey Churbanov   omp_event_handle_t evt;
54405037c4SAndrey Churbanov } *ptask, kmp_task_t;
55405037c4SAndrey Churbanov 
56405037c4SAndrey Churbanov typedef struct DEP {
57405037c4SAndrey Churbanov   size_t addr;
58405037c4SAndrey Churbanov   size_t len;
59*77c2b623SIlya Leoshkevich   unsigned char flags;
60405037c4SAndrey Churbanov } dep;
61405037c4SAndrey Churbanov 
62405037c4SAndrey Churbanov typedef int(* task_entry_t)( int, ptask );
63405037c4SAndrey Churbanov 
64405037c4SAndrey Churbanov #ifdef __cplusplus
65405037c4SAndrey Churbanov extern "C" {
66405037c4SAndrey Churbanov #endif
67405037c4SAndrey Churbanov extern int  __kmpc_global_thread_num(void *id_ref);
68405037c4SAndrey Churbanov extern int** __kmpc_omp_task_alloc(id *loc, int gtid, int flags,
69405037c4SAndrey Churbanov                                    size_t sz, size_t shar, task_entry_t rtn);
70405037c4SAndrey Churbanov extern int __kmpc_omp_task_with_deps(id *loc, int gtid, ptask task, int nd,
71405037c4SAndrey Churbanov                dep *dep_lst, int nd_noalias, dep *noalias_dep_lst);
72405037c4SAndrey Churbanov extern int __kmpc_omp_task(id *loc, int gtid, kmp_task_t *task);
73405037c4SAndrey Churbanov extern omp_event_handle_t __kmpc_task_allow_completion_event(
74405037c4SAndrey Churbanov                               ident_t *loc_ref, int gtid, kmp_task_t *task);
75405037c4SAndrey Churbanov #ifdef __cplusplus
76405037c4SAndrey Churbanov }
77405037c4SAndrey Churbanov #endif
78405037c4SAndrey Churbanov 
79405037c4SAndrey Churbanov int volatile checker;
80405037c4SAndrey Churbanov 
81405037c4SAndrey Churbanov // User's code, outlined into task entry
task_entry(int gtid,ptask task)82405037c4SAndrey Churbanov int task_entry(int gtid, ptask task) {
83405037c4SAndrey Churbanov   checker = 1;
84405037c4SAndrey Churbanov   return 0;
85405037c4SAndrey Churbanov }
86405037c4SAndrey Churbanov 
main()87405037c4SAndrey Churbanov int main() {
88405037c4SAndrey Churbanov   int i, j, gtid = __kmpc_global_thread_num(NULL);
89405037c4SAndrey Churbanov   int nt = omp_get_max_threads();
90405037c4SAndrey Churbanov   ptask task;
91405037c4SAndrey Churbanov   pshareds psh;
92405037c4SAndrey Churbanov   checker = 0;
93405037c4SAndrey Churbanov   omp_set_dynamic(0);
94405037c4SAndrey Churbanov   #pragma omp parallel //num_threads(N)
95405037c4SAndrey Churbanov   {
96405037c4SAndrey Churbanov     #pragma omp master
97405037c4SAndrey Churbanov     {
98405037c4SAndrey Churbanov       #pragma omp task depend(inout:nt)
99405037c4SAndrey Churbanov       {
100405037c4SAndrey Churbanov         my_sleep(2.0);
101405037c4SAndrey Churbanov       }
102405037c4SAndrey Churbanov       int gtid = __kmpc_global_thread_num(NULL);
103405037c4SAndrey Churbanov       omp_event_handle_t evt;
104405037c4SAndrey Churbanov /*
105405037c4SAndrey Churbanov       #pragma omp task detach(evt)
106405037c4SAndrey Churbanov       {}
107405037c4SAndrey Churbanov */
108405037c4SAndrey Churbanov       task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,
109405037c4SAndrey Churbanov                         sizeof(struct task),sizeof(struct shar),&task_entry);
110405037c4SAndrey Churbanov       psh = task->shareds;
111405037c4SAndrey Churbanov       evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
112405037c4SAndrey Churbanov       task->evt = evt;
113405037c4SAndrey Churbanov 
114405037c4SAndrey Churbanov       dep sdep;
115405037c4SAndrey Churbanov       sdep.addr = (size_t)&nt;
116405037c4SAndrey Churbanov       sdep.len = 0L;
117405037c4SAndrey Churbanov       sdep.flags = 3;
118405037c4SAndrey Churbanov 
119405037c4SAndrey Churbanov       __kmpc_omp_task_with_deps(NULL,gtid,task,1,&sdep,0,0);
120405037c4SAndrey Churbanov       //__kmpc_omp_task(NULL, gtid, task);
121405037c4SAndrey Churbanov 
122405037c4SAndrey Churbanov       omp_fulfill_event(evt);
123405037c4SAndrey Churbanov 
124405037c4SAndrey Churbanov       #pragma omp taskwait
125405037c4SAndrey Churbanov       ;
126405037c4SAndrey Churbanov //      printf("after tw %d\n", omp_get_thread_num());
127405037c4SAndrey Churbanov     } // end master
128405037c4SAndrey Churbanov   } // end parallel
129405037c4SAndrey Churbanov 
130405037c4SAndrey Churbanov   // check results
131405037c4SAndrey Churbanov   if (checker == 1) {
132405037c4SAndrey Churbanov     printf("passed\n");
133405037c4SAndrey Churbanov     return 0;
134405037c4SAndrey Churbanov   } else {
135405037c4SAndrey Churbanov     printf("failed\n");
136405037c4SAndrey Churbanov     return 1;
137405037c4SAndrey Churbanov   }
138405037c4SAndrey Churbanov }
139