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