1// { dg-do run } 2// { dg-set-target-env-var OMP_CANCELLATION "true" } 3 4#include <omp.h> 5#include "cancel-test.h" 6 7__attribute__((noinline, noclone)) int 8foo (int *x) 9{ 10 S a, b, c, d, e; 11 int v = 0, w = 0; 12 #pragma omp parallel num_threads (32) shared (v, w) private (c, d) firstprivate (e) 13 { 14 S g; 15 int i; 16 c.bump (); 17 e.bump (); 18 #pragma omp for private (d, g) firstprivate (b) 19 for (i = 0; i < 1000; ++i) 20 { 21 b.bump (); 22 d.bump (); 23 g.bump (); 24 #pragma omp cancel for if (x[0]) 25 abort (); 26 } 27 #pragma omp for private (d, g) firstprivate (b) 28 for (i = 0; i < 1000; ++i) 29 { 30 b.bump (); 31 d.bump (); 32 g.bump (); 33 #pragma omp cancel for if (x[1]) 34 #pragma omp atomic 35 v++; 36 } 37 #pragma omp for private (d, g) firstprivate (b) 38 for (i = 0; i < 1000; ++i) 39 { 40 b.bump (); 41 d.bump (); 42 g.bump (); 43 #pragma omp cancel for if (x[2]) 44 #pragma omp atomic 45 w += 8; 46 } 47 #pragma omp for private (d, g) firstprivate (b) 48 for (i = 0; i < 1000; ++i) 49 { 50 b.bump (); 51 d.bump (); 52 g.bump (); 53 #pragma omp cancel for if (x[3]) 54 #pragma omp atomic 55 v += 2; 56 } 57 } 58 if (v != 3000 || w != 0) 59 abort (); 60 #pragma omp parallel num_threads (32) shared (v, w) private (c, d) firstprivate (e) 61 { 62 S g, h; 63 int i; 64 c.bump (); 65 e.bump (); 66 /* None of these cancel directives should actually cancel anything, 67 but the compiler shouldn't know that and thus should use cancellable 68 barriers at the end of all the workshares. */ 69 #pragma omp cancel parallel if (omp_get_thread_num () == 1 && x[4]) 70 #pragma omp for private (d, g) firstprivate (b) 71 for (i = 0; i < 1000; ++i) 72 { 73 b.bump (); 74 d.bump (); 75 g.bump (); 76 #pragma omp cancel for if (x[0]) 77 abort (); 78 } 79 #pragma omp cancel parallel if (omp_get_thread_num () == 2 && x[4]) 80 #pragma omp for private (d, g) firstprivate (b) 81 for (i = 0; i < 1000; ++i) 82 { 83 b.bump (); 84 d.bump (); 85 g.bump (); 86 #pragma omp cancel for if (x[1]) 87 #pragma omp atomic 88 v++; 89 } 90 #pragma omp cancel parallel if (omp_get_thread_num () == 3 && x[4]) 91 #pragma omp for private (d, g) firstprivate (b) 92 for (i = 0; i < 1000; ++i) 93 { 94 b.bump (); 95 d.bump (); 96 g.bump (); 97 #pragma omp cancel for if (x[2]) 98 #pragma omp atomic 99 w += 8; 100 } 101 #pragma omp cancel parallel if (omp_get_thread_num () == 4 && x[4]) 102 #pragma omp for private (d, g) firstprivate (b) 103 for (i = 0; i < 1000; ++i) 104 { 105 b.bump (); 106 d.bump (); 107 g.bump (); 108 #pragma omp cancel for if (x[3]) 109 #pragma omp atomic 110 v += 2; 111 } 112 #pragma omp cancel parallel if (omp_get_thread_num () == 5 && x[4]) 113 } 114 if (v != 6000 || w != 0) 115 abort (); 116 return 0; 117} 118 119int 120main () 121{ 122 int x[] = { 1, 0, 1, 0, 0 }; 123 if (omp_get_cancellation ()) 124 foo (x); 125 S::verify (); 126} 127