cancel-for-2.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* { dg-do run } */
  2. /* { dg-set-target-env-var OMP_CANCELLATION "true" } */
  3. #include <stdlib.h>
  4. #include <omp.h>
  5. __attribute__((noinline, noclone)) int
  6. foo (int *x)
  7. {
  8. int v = 0, w = 0;
  9. #pragma omp parallel num_threads (32) shared (v, w)
  10. {
  11. int i;
  12. #pragma omp for
  13. for (i = 0; i < 1000; ++i)
  14. {
  15. #pragma omp cancel for if (x[0])
  16. abort ();
  17. }
  18. #pragma omp for
  19. for (i = 0; i < 1000; ++i)
  20. {
  21. #pragma omp cancel for if (cancel: x[1])
  22. #pragma omp atomic
  23. v++;
  24. }
  25. #pragma omp for
  26. for (i = 0; i < 1000; ++i)
  27. {
  28. #pragma omp cancel for if (x[2])
  29. #pragma omp atomic
  30. w += 8;
  31. }
  32. #pragma omp for
  33. for (i = 0; i < 1000; ++i)
  34. {
  35. #pragma omp cancel for if ( cancel : x[3])
  36. #pragma omp atomic
  37. v += 2;
  38. }
  39. }
  40. if (v != 3000 || w != 0)
  41. abort ();
  42. #pragma omp parallel num_threads (32) shared (v, w)
  43. {
  44. int i;
  45. /* None of these cancel directives should actually cancel anything,
  46. but the compiler shouldn't know that and thus should use cancellable
  47. barriers at the end of all the workshares. */
  48. #pragma omp cancel parallel if (omp_get_thread_num () == 1 && x[4])
  49. #pragma omp for
  50. for (i = 0; i < 1000; ++i)
  51. {
  52. #pragma omp cancel for if (x[0])
  53. abort ();
  54. }
  55. #pragma omp cancel parallel if (cancel:omp_get_thread_num () == 2 && x[4])
  56. #pragma omp for
  57. for (i = 0; i < 1000; ++i)
  58. {
  59. #pragma omp cancel for if (x[1])
  60. #pragma omp atomic
  61. v++;
  62. }
  63. #pragma omp cancel parallel if (omp_get_thread_num () == 3 && x[4])
  64. #pragma omp for
  65. for (i = 0; i < 1000; ++i)
  66. {
  67. #pragma omp cancel for if (x[2])
  68. #pragma omp atomic
  69. w += 8;
  70. }
  71. #pragma omp cancel parallel if (omp_get_thread_num () == 4 && x[4])
  72. #pragma omp for
  73. for (i = 0; i < 1000; ++i)
  74. {
  75. #pragma omp cancel for if (x[3])
  76. #pragma omp atomic
  77. v += 2;
  78. }
  79. #pragma omp cancel parallel if (omp_get_thread_num () == 5 && x[4])
  80. }
  81. if (v != 6000 || w != 0)
  82. abort ();
  83. return 0;
  84. }
  85. int
  86. main ()
  87. {
  88. int x[] = { 1, 0, 1, 0, 0 };
  89. if (omp_get_cancellation ())
  90. foo (x);
  91. return 0;
  92. }