1 // RUN: %libomp-compile && env OMP_MAX_TASK_PRIORITY='2' %libomp-run 2 3 // Test OMP 4.5 task priorities 4 // Higher priority task supposed to be executed before lower priority task. 5 6 #include <stdio.h> 7 #include <omp.h> 8 9 #include "omp_my_sleep.h" 10 // delay(n) - sleep n ms 11 #define delay(n) my_sleep(((double)n)/1000.0) 12 13 int main ( void ) { 14 int passed; 15 passed = (omp_get_max_task_priority() == 2); 16 printf("Got %d max priority via env\n", omp_get_max_task_priority()); 17 if(!passed) { 18 printf( "failed\n" ); 19 return 1; 20 } 21 printf("parallel 1 spawns 4 tasks for primary thread to execute\n"); 22 #pragma omp parallel num_threads(2) 23 { 24 int th = omp_get_thread_num(); 25 if (th == 0) // primary thread 26 { 27 #pragma omp task priority(1) 28 { // middle priority 29 int val, t = omp_get_thread_num(); 30 #pragma omp atomic capture 31 val = passed++; 32 printf("P1: val = %d, thread gen %d, thread exe %d\n", val, th, t); 33 delay(10); // sleep 10 ms 34 } 35 #pragma omp task priority(2) 36 { // high priority 37 int val, t = omp_get_thread_num(); 38 #pragma omp atomic capture 39 val = passed++; 40 printf("P2: val = %d, thread gen %d, thread exe %d\n", val, th, t); 41 delay(20); // sleep 20 ms 42 } 43 #pragma omp task priority(0) 44 { // low priority specified explicitly 45 int val, t = omp_get_thread_num(); 46 #pragma omp atomic capture 47 val = passed++; 48 printf("P0exp: val = %d, thread gen %d, thread exe %d\n", val, th, t); 49 delay(1); // sleep 1 ms 50 } 51 #pragma omp task 52 { // low priority by default 53 int val, t = omp_get_thread_num(); 54 #pragma omp atomic capture 55 val = passed++; 56 printf("P0imp: val = %d, thread gen %d, thread exe %d\n", val, th, t); 57 delay(1); // sleep 1 ms 58 } 59 } else { 60 // wait for the primary thread to finish all tasks 61 int wait = 0; 62 do { 63 delay(5); 64 #pragma omp atomic read 65 wait = passed; 66 } while (wait < 5); 67 } 68 } 69 printf("parallel 2 spawns 4 tasks for worker thread to execute\n"); 70 #pragma omp parallel num_threads(2) 71 { 72 int th = omp_get_thread_num(); 73 if (th == 0) // primary thread 74 { 75 #pragma omp task priority(1) 76 { // middle priority 77 int val, t = omp_get_thread_num(); 78 #pragma omp atomic capture 79 val = passed++; 80 printf("P1: val = %d, thread gen %d, thread exe %d\n", val, th, t); 81 delay(10); // sleep 10 ms 82 } 83 #pragma omp task priority(2) 84 { // high priority 85 int val, t = omp_get_thread_num(); 86 #pragma omp atomic capture 87 val = passed++; 88 printf("P2: val = %d, thread gen %d, thread exe %d\n", val, th, t); 89 delay(20); // sleep 20 ms 90 } 91 #pragma omp task priority(0) 92 { // low priority specified explicitly 93 int val, t = omp_get_thread_num(); 94 #pragma omp atomic capture 95 val = passed++; 96 printf("P0exp: val = %d, thread gen %d, thread exe %d\n", val, th, t); 97 delay(1); // sleep 1 ms 98 } 99 #pragma omp task 100 { // low priority by default 101 int val, t = omp_get_thread_num(); 102 #pragma omp atomic capture 103 val = passed++; 104 printf("P0imp: val = %d, thread gen %d, thread exe %d\n", val, th, t); 105 delay(1); // sleep 1 ms 106 } 107 // signal creation of all tasks: passed = 5 + 1 = 6 108 #pragma omp atomic 109 passed++; 110 // wait for completion of all 4 tasks 111 int wait = 0; 112 do { 113 delay(5); 114 #pragma omp atomic read 115 wait = passed; 116 } while (wait < 10); // passed = 6 + 4 = 10 117 } else { 118 // wait for the primary thread to create all tasks 119 int wait = 0; 120 do { 121 delay(5); 122 #pragma omp atomic read 123 wait = passed; 124 } while (wait < 6); 125 // go execute 4 tasks created by primary thread 126 } 127 } 128 if (passed != 10) { 129 printf("failed, passed = %d (should be 10)\n", passed); 130 return 1; 131 } 132 printf("passed\n"); 133 return 0; 134 } 135 // CHECK: parallel 1 136 // CHECK-NEXT: P2 137 // CHECK-NEXT: P1 138 // CHECK-NEXT: P0 139 // CHECK-NEXT: P0 140 // CHECK-NEXT: parallel 2 141 // CHECK-NEXT: P2 142 // CHECK-NEXT: P1 143 // CHECK-NEXT: P0 144 // CHECK-NEXT: P0 145 // CHECK: passed 146