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