12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- /* { dg-do run } */
- #include <omp.h>
- #include <stdio.h>
- extern void abort (void);
- #define NUMBER_OF_THREADS 4
- int synch[NUMBER_OF_THREADS];
- int work[NUMBER_OF_THREADS];
- int result[NUMBER_OF_THREADS];
- int
- fn1 (int i)
- {
- return i * 2;
- }
- int
- fn2 (int a, int b)
- {
- return a + b;
- }
- int
- main ()
- {
- int i, iam, neighbor;
- omp_set_num_threads (NUMBER_OF_THREADS);
- #pragma omp parallel private(iam,neighbor) shared(work,synch)
- {
- iam = omp_get_thread_num ();
- synch[iam] = 0;
- #pragma omp barrier
- /*Do computation into my portion of work array */
- work[iam] = fn1 (iam);
- /* Announce that I am done with my work. The first flush
- * ensures that my work is made visible before synch.
- * The second flush ensures that synch is made visible.
- */
- #pragma omp flush(work,synch)
- synch[iam] = 1;
- #pragma omp flush(synch)
- /* Wait for neighbor. The first flush ensures that synch is read
- * from memory, rather than from the temporary view of memory.
- * The second flush ensures that work is read from memory, and
- * is done so after the while loop exits.
- */
- neighbor = (iam > 0 ? iam : omp_get_num_threads ()) - 1;
- while (synch[neighbor] == 0)
- {
- #pragma omp flush(synch)
- }
- #pragma omp flush(work,synch)
- /* Read neighbor's values of work array */
- result[iam] = fn2 (work[neighbor], work[iam]);
- }
- /* output result here */
- for (i = 0; i < NUMBER_OF_THREADS; i++)
- {
- neighbor = (i > 0 ? i : NUMBER_OF_THREADS) - 1;
- if (result[i] != i * 2 + neighbor * 2)
- abort ();
- }
- return 0;
- }
|