118 lines · cpp
1// RUN: %libomp-cxx-compile-and-run2 3#include <omp.h>4 5#include <chrono>6#include <cstdint>7#include <iostream>8#include <thread>9 10// detached11#define PTASK_FLAG_DETACHABLE 0x4012 13// OpenMP RTL interfaces14using kmp_int32 = int32_t;15 16typedef struct ID {17 int reserved_1;18 int flags;19 int reserved_2;20 int reserved_3;21 char *psource;22} id;23 24// Compiler-generated code (emulation)25typedef struct ident {26 void *dummy; // not used in the library27} ident_t;28 29typedef enum kmp_event_type_t {30 KMP_EVENT_UNINITIALIZED = 0,31 KMP_EVENT_ALLOW_COMPLETION = 132} kmp_event_type_t;33 34typedef struct {35 kmp_event_type_t type;36 union {37 void *task;38 } ed;39} kmp_event_t;40 41typedef struct shar { // shareds used in the task42} * pshareds;43 44typedef struct task {45 pshareds shareds;46 int (*routine)(int, struct task *);47 int part_id;48 // void *destructor_thunk; // optional, needs flag setting if provided49 // int priority; // optional, needs flag setting if provided50 // ------------------------------51 // privates used in the task:52 omp_event_handle_t evt;53} * ptask, kmp_task_t;54 55typedef int (*task_entry_t)(int, ptask);56 57#ifdef __cplusplus58extern "C" {59#endif60extern int __kmpc_global_thread_num(void *id_ref);61extern int **__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,62 size_t shar, task_entry_t rtn);63extern kmp_int32 __kmpc_omp_task(ident_t *loc_ref, kmp_int32 gtid,64 kmp_task_t *new_task);65extern omp_event_handle_t __kmpc_task_allow_completion_event(ident_t *loc_ref,66 int gtid,67 kmp_task_t *task);68#ifdef __cplusplus69}70#endif71 72int volatile checker;73 74void target(ptask task) {75 std::this_thread::sleep_for(std::chrono::seconds(3));76 checker = 1;77 omp_fulfill_event(task->evt);78}79 80// User's code81int task_entry(int gtid, ptask task) {82 std::thread t(target, task);83 t.detach();84 return 0;85}86 87int main(int argc, char *argv[]) {88 int gtid = __kmpc_global_thread_num(nullptr);89 checker = 0;90 91 /*92 #pragma omp task detach(evt)93 {}94 */95 std::cout << "detaching...\n";96 ptask task = (ptask)__kmpc_omp_task_alloc(97 nullptr, gtid, PTASK_FLAG_DETACHABLE, sizeof(struct task),98 sizeof(struct shar), &task_entry);99 omp_event_handle_t evt =100 (omp_event_handle_t)__kmpc_task_allow_completion_event(nullptr, gtid,101 task);102 task->evt = evt;103 104 __kmpc_omp_task(nullptr, gtid, task);105 106#pragma omp taskwait107 108 // check results109 if (checker == 1) {110 std::cout << "PASS\n";111 return 0;112 }113 114 return 1;115}116 117// CHECK: PASS118