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