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