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