153 lines · c
1// RUN: %libomp-compile-and-run2 3// Tests OMP 5.0 task dependences "mutexinoutset", emulates compiler codegen4// Mutually exclusive tasks get same input dependency info array5//6// Task tree created:7// task0 task18// \ / \9// task2 task510// / \11// task3 task412// / \13// task6 <-->task7 (these two are mutually exclusive)14// \ /15// task816//17#include <stdio.h>18#include <omp.h>19 20#ifdef _WIN3221#include <windows.h>22#define mysleep(n) Sleep(n)23#else24#include <unistd.h>25#define mysleep(n) usleep((n)*1000)26#endif27 28static int checker = 0; // to check if two tasks run simultaneously29static int err = 0;30#ifndef DELAY31#define DELAY 10032#endif33 34// ---------------------------------------------------------------------------35// internal data to emulate compiler codegen36typedef int(*entry_t)(int, int**);37typedef struct DEP {38 size_t addr;39 size_t len;40 unsigned char flags;41} dep;42typedef struct ID {43 int reserved_1;44 int flags;45 int reserved_2;46 int reserved_3;47 char *psource;48} id;49 50int thunk(int gtid, int** pshareds) {51 int t = **pshareds;52 int th = omp_get_thread_num();53 #pragma omp atomic54 ++checker;55 printf("task __%d, th %d\n", t, th);56 if (checker != 1) {57 err++;58 printf("Error1, checker %d != 1\n", checker);59 }60 mysleep(DELAY);61 if (checker != 1) {62 err++;63 printf("Error2, checker %d != 1\n", checker);64 }65 #pragma omp atomic66 --checker;67 return 0;68}69 70#ifdef __cplusplus71extern "C" {72#endif73int __kmpc_global_thread_num(id*);74extern int** __kmpc_omp_task_alloc(id *loc, int gtid, int flags,75 size_t sz, size_t shar, entry_t rtn);76int77__kmpc_omp_task_with_deps(id *loc, int gtid, int **task, int nd, dep *dep_lst,78 int nd_noalias, dep *noalias_dep_lst);79static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};80#ifdef __cplusplus81} // extern "C"82#endif83// End of internal data84// ---------------------------------------------------------------------------85 86int main()87{88 int i1,i2,i3,i4;89 omp_set_num_threads(2);90 #pragma omp parallel91 {92 #pragma omp single nowait93 {94 dep sdep[2];95 int **ptr;96 int gtid = __kmpc_global_thread_num(&loc);97 int t = omp_get_thread_num();98 #pragma omp task depend(in: i1, i2)99 { int th = omp_get_thread_num();100 printf("task 0_%d, th %d\n", t, th);101 mysleep(DELAY); }102 #pragma omp task depend(in: i1, i3)103 { int th = omp_get_thread_num();104 printf("task 1_%d, th %d\n", t, th);105 mysleep(DELAY); }106 #pragma omp task depend(in: i2) depend(out: i1)107 { int th = omp_get_thread_num();108 printf("task 2_%d, th %d\n", t, th);109 mysleep(DELAY); }110 #pragma omp task depend(in: i1)111 { int th = omp_get_thread_num();112 printf("task 3_%d, th %d\n", t, th);113 mysleep(DELAY); }114 #pragma omp task depend(out: i2)115 { int th = omp_get_thread_num();116 printf("task 4_%d, th %d\n", t, th);117 mysleep(DELAY+5); } // wait a bit longer than task 3118 #pragma omp task depend(out: i3)119 { int th = omp_get_thread_num();120 printf("task 5_%d, th %d\n", t, th);121 mysleep(DELAY); }122// compiler codegen start123 // task1124 ptr = __kmpc_omp_task_alloc(&loc, gtid, 0, 28, 16, thunk);125 sdep[0].addr = (size_t)&i1;126 sdep[0].len = 0; // not used127 sdep[0].flags = 4; // mx128 sdep[1].addr = (size_t)&i4;129 sdep[1].len = 0; // not used130 sdep[1].flags = 4; // mx131 **ptr = t + 10; // init single shared variable132 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);133 134 // task2135 ptr = __kmpc_omp_task_alloc(&loc, gtid, 0, 28, 16, thunk);136 **ptr = t + 20; // init single shared variable137 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);138// compiler codegen end139 #pragma omp task depend(in: i1)140 { int th = omp_get_thread_num();141 printf("task 8_%d, th %d\n", t, th);142 mysleep(DELAY); }143 } // single144 } // parallel145 if (err == 0) {146 printf("passed\n");147 return 0;148 } else {149 printf("failed\n");150 return 1;151 }152}153