brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 6f0dff4 Raw
105 lines · c
1// RUN: %libomp-compile-and-run2 3#include <stdio.h>4#include <stdlib.h>5#include <omp.h>6#include "omp_my_sleep.h"7 8int a = 0, b = 0;9int task_grabbed = 0, task_can_proceed = 0;10int task2_grabbed = 0, task2_can_proceed = 0;11 12static void wait_on_flag(int *flag) {13  int flag_value;14  int timelimit = 30;15  int secs = 0;16  do {17    #pragma omp atomic read18    flag_value = *flag;19    my_sleep(1.0);20    secs++;21    if (secs == timelimit) {22      fprintf(stderr, "error: timeout in wait_on_flag()\n");23      exit(EXIT_FAILURE);24    }25  } while (flag_value == 0);26}27 28static void signal_flag(int *flag) {29  #pragma omp atomic30  (*flag)++;31}32 33int main(int argc, char** argv) {34 35  // Ensure two threads are running36  int num_threads = omp_get_max_threads();37  if (num_threads < 2)38    omp_set_num_threads(2);39 40  #pragma omp parallel shared(a)41  {42    int a_value;43    // Let us be extra safe here44    if (omp_get_num_threads() > 1) {45      #pragma omp single nowait46      {47        // Schedule independent child task that48        // waits to be flagged after sebsequent taskwait depend()49        #pragma omp task50        {51          signal_flag(&task_grabbed);52          wait_on_flag(&task_can_proceed);53        }54        // Let another worker thread grab the task to execute55        wait_on_flag(&task_grabbed);56        // This should be ignored since the task above has57        // no dependency information58        #pragma omp task if(0) depend(inout: a)59        {}60        // Signal the independent task to proceed61        signal_flag(&task_can_proceed);62 63        // Schedule child task with dependencies that taskwait does64        // not care about65        #pragma omp task depend(inout: b)66        {67          signal_flag(&task2_grabbed);68          wait_on_flag(&task2_can_proceed);69          #pragma omp atomic70          b++;71        }72        // Let another worker thread grab the task to execute73        wait_on_flag(&task2_grabbed);74        // This should be ignored since the task above has75        // dependency information on b instead of a76        #pragma omp task if(0) depend(inout: a)77        {}78        // Signal the task to proceed79        signal_flag(&task2_can_proceed);80 81        // Generate one child task for taskwait82        #pragma omp task shared(a) depend(inout: a)83        {84          my_sleep(1.0);85          #pragma omp atomic86          a++;87        }88        #pragma omp task if(0) depend(inout: a)89        {}90 91        #pragma omp atomic read92        a_value = a;93 94        if (a_value != 1) {95          fprintf(stderr, "error: dependent task was not executed before "96                          "taskwait finished\n");97          exit(EXIT_FAILURE);98        }99      } // #pragma omp single100    } // if (num_threads > 1)101  } // #pragma omp parallel102 103  return EXIT_SUCCESS;104}105