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