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
foo(int * x)8 foo (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
119 int
main()120 main ()
121 {
122 int x[] = { 1, 0, 1, 0, 0 };
123 if (omp_get_cancellation ())
124 foo (x);
125 S::verify ();
126 }
127