brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · 1e2b166 Raw
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