reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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;
  }
}