cancel-taskgroup-1.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /* { dg-do run } */
  2. /* { dg-set-target-env-var OMP_CANCELLATION "true" } */
  3. #include <stdlib.h>
  4. #include <omp.h>
  5. struct T { struct T *children[2]; int val; };
  6. struct T *
  7. search (struct T *tree, int val, int lvl)
  8. {
  9. if (tree == NULL || tree->val == val)
  10. return tree;
  11. struct T *ret = NULL;
  12. int i;
  13. for (i = 0; i < 2; i++)
  14. #pragma omp task shared(ret) if(lvl < 10)
  15. {
  16. struct T *r = search (tree->children[i], val, lvl + 1);
  17. if (r)
  18. {
  19. #pragma omp atomic write
  20. ret = r;
  21. #pragma omp cancel taskgroup
  22. }
  23. }
  24. #pragma omp taskwait
  25. return ret;
  26. }
  27. struct T *
  28. searchp (struct T *tree, int val)
  29. {
  30. struct T *ret;
  31. #pragma omp parallel shared(ret) firstprivate (tree, val)
  32. #pragma omp single
  33. #pragma omp taskgroup
  34. ret = search (tree, val, 0);
  35. return ret;
  36. }
  37. int
  38. main ()
  39. {
  40. /* Must be power of two minus 1. */
  41. int size = 0x7ffff;
  42. struct T *trees = (struct T *) malloc (size * sizeof (struct T));
  43. if (trees == NULL)
  44. return 0;
  45. int i, l = 1, b = 0;
  46. for (i = 0; i < size; i++)
  47. {
  48. if (i == l)
  49. {
  50. b = l;
  51. l = l * 2 + 1;
  52. }
  53. trees[i].val = i;
  54. trees[i].children[0] = l == size ? NULL : &trees[l + (i - b) * 2];
  55. trees[i].children[1] = l == size ? NULL : &trees[l + (i - b) * 2 + 1];
  56. }
  57. for (i = 0; i < 50; i++)
  58. {
  59. int v = random () & size;
  60. if (searchp (&trees[0], v) != &trees[v])
  61. abort ();
  62. }
  63. free (trees);
  64. return 0;
  65. }