110 lines · c
1// RUN: %libomp-compile-and-run2// UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-83 4// support for taskwait with depend clause introduced in clang-145// UNSUPPORTED: clang-5, clang-6, clang-6, clang-8, clang-9, clang-10, clang-11,6// clang-12, clang-137 8// icc does not yet support taskwait with depend clause9// XFAIL: icc10 11#include <stdio.h>12#include <stdlib.h>13#include <omp.h>14#include "omp_my_sleep.h"15 16int a = 0, b = 0;17int task_grabbed = 0, task_can_proceed = 0;18int task2_grabbed = 0, task2_can_proceed = 0;19 20static void wait_on_flag(int *flag) {21 int flag_value;22 int timelimit = 30;23 int secs = 0;24 do {25 #pragma omp atomic read26 flag_value = *flag;27 my_sleep(1.0);28 secs++;29 if (secs == timelimit) {30 fprintf(stderr, "error: timeout in wait_on_flag()\n");31 exit(EXIT_FAILURE);32 }33 } while (flag_value == 0);34}35 36static void signal_flag(int *flag) {37 #pragma omp atomic38 (*flag)++;39}40 41int main(int argc, char** argv) {42 43 // Ensure two threads are running44 int num_threads = omp_get_max_threads();45 if (num_threads < 2)46 omp_set_num_threads(2);47 48 #pragma omp parallel shared(a)49 {50 int a_value;51 // Let us be extra safe here52 if (omp_get_num_threads() > 1) {53 #pragma omp single nowait54 {55 // Schedule independent child task that56 // waits to be flagged after sebsequent taskwait depend()57 #pragma omp task58 {59 signal_flag(&task_grabbed);60 wait_on_flag(&task_can_proceed);61 }62 // Let another worker thread grab the task to execute63 wait_on_flag(&task_grabbed);64 // This should be ignored since the task above has65 // no dependency information66 #pragma omp taskwait depend(inout: a)67 // Signal the independent task to proceed68 signal_flag(&task_can_proceed);69 70 // Schedule child task with dependencies that taskwait does71 // not care about72 #pragma omp task depend(inout: b)73 {74 signal_flag(&task2_grabbed);75 wait_on_flag(&task2_can_proceed);76 #pragma omp atomic77 b++;78 }79 // Let another worker thread grab the task to execute80 wait_on_flag(&task2_grabbed);81 // This should be ignored since the task above has82 // dependency information on b instead of a83 #pragma omp taskwait depend(inout: a)84 // Signal the task to proceed85 signal_flag(&task2_can_proceed);86 87 // Generate one child task for taskwait88 #pragma omp task shared(a) depend(inout: a)89 {90 my_sleep(1.0);91 #pragma omp atomic92 a++;93 }94 #pragma omp taskwait depend(inout: a)95 96 #pragma omp atomic read97 a_value = a;98 99 if (a_value != 1) {100 fprintf(stderr, "error: dependent task was not executed before "101 "taskwait finished\n");102 exit(EXIT_FAILURE);103 }104 } // #pragma omp single105 } // if (num_threads > 1)106 } // #pragma omp parallel107 108 return EXIT_SUCCESS;109}110