xref: /llvm-project/openmp/runtime/test/tasking/kmp_detach_tasks_t3.c (revision 77c2b623ca4ce10ec1019b31706a055aad2580cd)
1 // RUN: %libomp-compile && env OMP_NUM_THREADS='3' %libomp-run
2 // RUN: %libomp-compile && env OMP_NUM_THREADS='1' %libomp-run
3 // The runtime currently does not get dependency information from GCC.
4 // UNSUPPORTED: gcc
5 
6 #include <stdio.h>
7 #include <omp.h>
8 #include "omp_my_sleep.h"
9 
10 // detached untied
11 #define PTASK_FLAG_DETACHABLE 0x40
12 
13 // OpenMP RTL interfaces
14 typedef unsigned long long kmp_uint64;
15 typedef long long kmp_int64;
16 
17 typedef struct ID {
18   int reserved_1;
19   int flags;
20   int reserved_2;
21   int reserved_3;
22   char *psource;
23 } id;
24 
25 // Compiler-generated code (emulation)
26 typedef struct ident {
27   void* dummy; // not used in the library
28 } ident_t;
29 
30 typedef enum kmp_event_type_t {
31   KMP_EVENT_UNINITIALIZED = 0,
32   KMP_EVENT_ALLOW_COMPLETION = 1
33 } kmp_event_type_t;
34 
35 typedef struct {
36   kmp_event_type_t type;
37   union {
38     void *task;
39   } ed;
40 } kmp_event_t;
41 
42 typedef struct shar { // shareds used in the task
43 } *pshareds;
44 
45 typedef struct task {
46   pshareds shareds;
47   int(*routine)(int,struct task*);
48   int part_id;
49 // void *destructor_thunk; // optional, needs flag setting if provided
50 // int priority; // optional, needs flag setting if provided
51 // ------------------------------
52 // privates used in the task:
53   omp_event_handle_t evt;
54 } *ptask, kmp_task_t;
55 
56 typedef struct DEP {
57   size_t addr;
58   size_t len;
59   unsigned char flags;
60 } dep;
61 
62 typedef int(* task_entry_t)( int, ptask );
63 
64 #ifdef __cplusplus
65 extern "C" {
66 #endif
67 extern int  __kmpc_global_thread_num(void *id_ref);
68 extern int** __kmpc_omp_task_alloc(id *loc, int gtid, int flags,
69                                    size_t sz, size_t shar, task_entry_t rtn);
70 extern int __kmpc_omp_task_with_deps(id *loc, int gtid, ptask task, int nd,
71                dep *dep_lst, int nd_noalias, dep *noalias_dep_lst);
72 extern int __kmpc_omp_task(id *loc, int gtid, kmp_task_t *task);
73 extern omp_event_handle_t __kmpc_task_allow_completion_event(
74                               ident_t *loc_ref, int gtid, kmp_task_t *task);
75 #ifdef __cplusplus
76 }
77 #endif
78 
79 int volatile checker;
80 
81 // User's code, outlined into task entry
task_entry(int gtid,ptask task)82 int task_entry(int gtid, ptask task) {
83   checker = 1;
84   return 0;
85 }
86 
main()87 int main() {
88   int i, j, gtid = __kmpc_global_thread_num(NULL);
89   int nt = omp_get_max_threads();
90   ptask task;
91   pshareds psh;
92   checker = 0;
93   omp_set_dynamic(0);
94   #pragma omp parallel //num_threads(N)
95   {
96     #pragma omp master
97     {
98       #pragma omp task depend(inout:nt)
99       {
100         my_sleep(2.0);
101       }
102       int gtid = __kmpc_global_thread_num(NULL);
103       omp_event_handle_t evt;
104 /*
105       #pragma omp task detach(evt)
106       {}
107 */
108       task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,
109                         sizeof(struct task),sizeof(struct shar),&task_entry);
110       psh = task->shareds;
111       evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
112       task->evt = evt;
113 
114       dep sdep;
115       sdep.addr = (size_t)&nt;
116       sdep.len = 0L;
117       sdep.flags = 3;
118 
119       __kmpc_omp_task_with_deps(NULL,gtid,task,1,&sdep,0,0);
120       //__kmpc_omp_task(NULL, gtid, task);
121 
122       omp_fulfill_event(evt);
123 
124       #pragma omp taskwait
125       ;
126 //      printf("after tw %d\n", omp_get_thread_num());
127     } // end master
128   } // end parallel
129 
130   // check results
131   if (checker == 1) {
132     printf("passed\n");
133     return 0;
134   } else {
135     printf("failed\n");
136     return 1;
137   }
138 }
139