1 // RUN: %libomp-cxx-compile-and-run 2 3 #include <omp.h> 4 5 #include <chrono> 6 #include <iostream> 7 #include <thread> 8 9 // detached 10 #define PTASK_FLAG_DETACHABLE 0x40 11 12 // OpenMP RTL interfaces 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, size_t sz, 61 size_t shar, task_entry_t rtn); 62 extern int __kmpc_omp_task(id *loc, kmp_int64 gtid, kmp_task_t *task); 63 extern omp_event_handle_t __kmpc_task_allow_completion_event(ident_t *loc_ref, 64 int gtid, 65 kmp_task_t *task); 66 #ifdef __cplusplus 67 } 68 #endif 69 70 int volatile checker; 71 72 void target(ptask task) { 73 std::this_thread::sleep_for(std::chrono::seconds(3)); 74 checker = 1; 75 omp_fulfill_event(task->evt); 76 } 77 78 // User's code 79 int task_entry(int gtid, ptask task) { 80 std::thread t(target, task); 81 t.detach(); 82 return 0; 83 } 84 85 int main(int argc, char *argv[]) { 86 int gtid = __kmpc_global_thread_num(nullptr); 87 checker = 0; 88 89 /* 90 #pragma omp task detach(evt) 91 {} 92 */ 93 std::cout << "detaching...\n"; 94 ptask task = (ptask)__kmpc_omp_task_alloc( 95 nullptr, gtid, PTASK_FLAG_DETACHABLE, sizeof(struct task), 96 sizeof(struct shar), &task_entry); 97 omp_event_handle_t evt = 98 (omp_event_handle_t)__kmpc_task_allow_completion_event(nullptr, gtid, 99 task); 100 task->evt = evt; 101 102 __kmpc_omp_task(nullptr, gtid, task); 103 104 #pragma omp taskwait 105 106 // check results 107 if (checker == 1) { 108 std::cout << "PASS\n"; 109 return 0; 110 } 111 112 return 1; 113 } 114 115 // CHECK: PASS 116