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
12typedef unsigned long long kmp_uint64;
13typedef long long kmp_int64;
14
15typedef 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)
24typedef struct ident {
25 void* dummy; // not used in the library
26} ident_t;
27
28typedef enum kmp_event_type_t {
29 KMP_EVENT_UNINITIALIZED = 0,
30 KMP_EVENT_ALLOW_COMPLETION = 1
31} kmp_event_type_t;
32
33typedef struct {
34 kmp_event_type_t type;
35 union {
36 void *task;
37 } ed;
38} kmp_event_t;
39
40typedef struct shar { // shareds used in the task
41} *pshareds;
42
43typedef 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
54typedef int(* task_entry_t)( int, ptask );
55
56#ifdef __cplusplus
57extern "C" {
58#endif
59extern int __kmpc_global_thread_num(void *id_ref);
60extern int** __kmpc_omp_task_alloc(id *loc, int gtid, int flags,
61 size_t sz, size_t shar, task_entry_t rtn);
62extern int __kmpc_omp_task(id *loc, int gtid, kmp_task_t *task);
63extern 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
69int volatile checker;
70
71// User's code, outlined into task entry
72int task_entry(int gtid, ptask task) {
73 my_sleep(2.0);
74 checker = 1;
75 return 0;
76}
77
78int 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 sz: sizeof(struct task),shar: sizeof(struct shar),rtn: &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(format: "passed\n");
111 return 0;
112 } else {
113 printf(format: "failed\n");
114 return 1;
115 }
116}
117

source code of openmp/runtime/test/tasking/kmp_detach_tasks_t2.c