a.18.1.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /* { dg-do run } */
  2. #include <omp.h>
  3. #include <stdio.h>
  4. extern void abort (void);
  5. #define NUMBER_OF_THREADS 4
  6. int synch[NUMBER_OF_THREADS];
  7. int work[NUMBER_OF_THREADS];
  8. int result[NUMBER_OF_THREADS];
  9. int
  10. fn1 (int i)
  11. {
  12. return i * 2;
  13. }
  14. int
  15. fn2 (int a, int b)
  16. {
  17. return a + b;
  18. }
  19. int
  20. main ()
  21. {
  22. int i, iam, neighbor;
  23. omp_set_num_threads (NUMBER_OF_THREADS);
  24. #pragma omp parallel private(iam,neighbor) shared(work,synch)
  25. {
  26. iam = omp_get_thread_num ();
  27. synch[iam] = 0;
  28. #pragma omp barrier
  29. /*Do computation into my portion of work array */
  30. work[iam] = fn1 (iam);
  31. /* Announce that I am done with my work. The first flush
  32. * ensures that my work is made visible before synch.
  33. * The second flush ensures that synch is made visible.
  34. */
  35. #pragma omp flush(work,synch)
  36. synch[iam] = 1;
  37. #pragma omp flush(synch)
  38. /* Wait for neighbor. The first flush ensures that synch is read
  39. * from memory, rather than from the temporary view of memory.
  40. * The second flush ensures that work is read from memory, and
  41. * is done so after the while loop exits.
  42. */
  43. neighbor = (iam > 0 ? iam : omp_get_num_threads ()) - 1;
  44. while (synch[neighbor] == 0)
  45. {
  46. #pragma omp flush(synch)
  47. }
  48. #pragma omp flush(work,synch)
  49. /* Read neighbor's values of work array */
  50. result[iam] = fn2 (work[neighbor], work[iam]);
  51. }
  52. /* output result here */
  53. for (i = 0; i < NUMBER_OF_THREADS; i++)
  54. {
  55. neighbor = (i > 0 ? i : NUMBER_OF_THREADS) - 1;
  56. if (result[i] != i * 2 + neighbor * 2)
  57. abort ();
  58. }
  59. return 0;
  60. }