13c31b784SShilei Tian // RUN: %libomp-cxx-compile-and-run
23c31b784SShilei Tian
33c31b784SShilei Tian #include <omp.h>
43c31b784SShilei Tian
53c31b784SShilei Tian #include <chrono>
6*af6511d7SShilei Tian #include <cstdint>
73c31b784SShilei Tian #include <iostream>
83c31b784SShilei Tian #include <thread>
93c31b784SShilei Tian
103c31b784SShilei Tian // detached
113c31b784SShilei Tian #define PTASK_FLAG_DETACHABLE 0x40
123c31b784SShilei Tian
133c31b784SShilei Tian // OpenMP RTL interfaces
14*af6511d7SShilei Tian using kmp_int32 = int32_t;
153c31b784SShilei Tian
163c31b784SShilei Tian typedef struct ID {
173c31b784SShilei Tian int reserved_1;
183c31b784SShilei Tian int flags;
193c31b784SShilei Tian int reserved_2;
203c31b784SShilei Tian int reserved_3;
213c31b784SShilei Tian char *psource;
223c31b784SShilei Tian } id;
233c31b784SShilei Tian
243c31b784SShilei Tian // Compiler-generated code (emulation)
253c31b784SShilei Tian typedef struct ident {
263c31b784SShilei Tian void *dummy; // not used in the library
273c31b784SShilei Tian } ident_t;
283c31b784SShilei Tian
293c31b784SShilei Tian typedef enum kmp_event_type_t {
303c31b784SShilei Tian KMP_EVENT_UNINITIALIZED = 0,
313c31b784SShilei Tian KMP_EVENT_ALLOW_COMPLETION = 1
323c31b784SShilei Tian } kmp_event_type_t;
333c31b784SShilei Tian
343c31b784SShilei Tian typedef struct {
353c31b784SShilei Tian kmp_event_type_t type;
363c31b784SShilei Tian union {
373c31b784SShilei Tian void *task;
383c31b784SShilei Tian } ed;
393c31b784SShilei Tian } kmp_event_t;
403c31b784SShilei Tian
413c31b784SShilei Tian typedef struct shar { // shareds used in the task
423c31b784SShilei Tian } * pshareds;
433c31b784SShilei Tian
443c31b784SShilei Tian typedef struct task {
453c31b784SShilei Tian pshareds shareds;
463c31b784SShilei Tian int (*routine)(int, struct task *);
473c31b784SShilei Tian int part_id;
483c31b784SShilei Tian // void *destructor_thunk; // optional, needs flag setting if provided
493c31b784SShilei Tian // int priority; // optional, needs flag setting if provided
503c31b784SShilei Tian // ------------------------------
513c31b784SShilei Tian // privates used in the task:
523c31b784SShilei Tian omp_event_handle_t evt;
533c31b784SShilei Tian } * ptask, kmp_task_t;
543c31b784SShilei Tian
553c31b784SShilei Tian typedef int (*task_entry_t)(int, ptask);
563c31b784SShilei Tian
573c31b784SShilei Tian #ifdef __cplusplus
583c31b784SShilei Tian extern "C" {
593c31b784SShilei Tian #endif
603c31b784SShilei Tian extern int __kmpc_global_thread_num(void *id_ref);
613c31b784SShilei Tian extern int **__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,
623c31b784SShilei Tian size_t shar, task_entry_t rtn);
63*af6511d7SShilei Tian extern kmp_int32 __kmpc_omp_task(ident_t *loc_ref, kmp_int32 gtid,
64*af6511d7SShilei Tian kmp_task_t *new_task);
653c31b784SShilei Tian extern omp_event_handle_t __kmpc_task_allow_completion_event(ident_t *loc_ref,
663c31b784SShilei Tian int gtid,
673c31b784SShilei Tian kmp_task_t *task);
683c31b784SShilei Tian #ifdef __cplusplus
693c31b784SShilei Tian }
703c31b784SShilei Tian #endif
713c31b784SShilei Tian
723c31b784SShilei Tian int volatile checker;
733c31b784SShilei Tian
target(ptask task)743c31b784SShilei Tian void target(ptask task) {
753c31b784SShilei Tian std::this_thread::sleep_for(std::chrono::seconds(3));
763c31b784SShilei Tian checker = 1;
773c31b784SShilei Tian omp_fulfill_event(task->evt);
783c31b784SShilei Tian }
793c31b784SShilei Tian
803c31b784SShilei Tian // User's code
task_entry(int gtid,ptask task)813c31b784SShilei Tian int task_entry(int gtid, ptask task) {
823c31b784SShilei Tian std::thread t(target, task);
833c31b784SShilei Tian t.detach();
843c31b784SShilei Tian return 0;
853c31b784SShilei Tian }
863c31b784SShilei Tian
main(int argc,char * argv[])873c31b784SShilei Tian int main(int argc, char *argv[]) {
883c31b784SShilei Tian int gtid = __kmpc_global_thread_num(nullptr);
893c31b784SShilei Tian checker = 0;
903c31b784SShilei Tian
913c31b784SShilei Tian /*
923c31b784SShilei Tian #pragma omp task detach(evt)
933c31b784SShilei Tian {}
943c31b784SShilei Tian */
953c31b784SShilei Tian std::cout << "detaching...\n";
963c31b784SShilei Tian ptask task = (ptask)__kmpc_omp_task_alloc(
973c31b784SShilei Tian nullptr, gtid, PTASK_FLAG_DETACHABLE, sizeof(struct task),
983c31b784SShilei Tian sizeof(struct shar), &task_entry);
993c31b784SShilei Tian omp_event_handle_t evt =
1003c31b784SShilei Tian (omp_event_handle_t)__kmpc_task_allow_completion_event(nullptr, gtid,
1013c31b784SShilei Tian task);
1023c31b784SShilei Tian task->evt = evt;
1033c31b784SShilei Tian
1043c31b784SShilei Tian __kmpc_omp_task(nullptr, gtid, task);
1053c31b784SShilei Tian
1063c31b784SShilei Tian #pragma omp taskwait
1073c31b784SShilei Tian
1083c31b784SShilei Tian // check results
1093c31b784SShilei Tian if (checker == 1) {
1103c31b784SShilei Tian std::cout << "PASS\n";
1113c31b784SShilei Tian return 0;
1123c31b784SShilei Tian }
1133c31b784SShilei Tian
1143c31b784SShilei Tian return 1;
1153c31b784SShilei Tian }
1163c31b784SShilei Tian
1173c31b784SShilei Tian // CHECK: PASS
118