1// { dg-do run }
2// { dg-set-target-env-var OMP_CANCELLATION "true" }
3
4#include <unistd.h>
5#include <omp.h>
6#include "cancel-test.h"
7
8static void
9foo (int *x)
10{
11  S a, b, c;
12  #pragma omp parallel firstprivate(x, c) num_threads (32) private (b)
13  {
14    S d;
15    b.bump ();
16    c.bump ();
17    int thr = omp_get_thread_num ();
18    switch (x[thr])
19      {
20      case 4:
21	#pragma omp cancel parallel
22	break;
23      case 3:
24	#pragma omp task
25	usleep (1000);
26	#pragma omp task
27	usleep (2000);
28	#pragma omp task
29	usleep (4000);
30	break;
31      case 2:
32	usleep (1000);
33	/* FALLTHRU */
34      case 1:
35	#pragma omp cancellation point parallel
36	break;
37      }
38    #pragma omp barrier
39    if (omp_get_cancellation ())
40      abort ();
41  }
42}
43
44int
45main ()
46{
47  int i, j, x[32] = { 0, 1, 2, 4, 2, 2, 1, 0 };
48  foo (x);
49  for (i = 0; i < 32; i++)
50    {
51      for (j = 0; j < 32; j++)
52	x[j] = rand () & 3;
53      x[rand () & 31] = 4;
54      foo (x);
55    }
56  S::verify ();
57}
58