xref: /openbsd-src/gnu/gcc/libgomp/testsuite/libgomp.c/loop-2.c (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert /* Validate static scheduling iteration dispatch.  We only test with
2*404b540aSrobert    even thread distributions here; there are multiple valid solutions
3*404b540aSrobert    for uneven thread distributions.  */
4*404b540aSrobert 
5*404b540aSrobert /* { dg-require-effective-target sync_int_long } */
6*404b540aSrobert 
7*404b540aSrobert #include <omp.h>
8*404b540aSrobert #include <string.h>
9*404b540aSrobert #include <assert.h>
10*404b540aSrobert #include "libgomp_g.h"
11*404b540aSrobert 
12*404b540aSrobert 
13*404b540aSrobert #define N 360
14*404b540aSrobert static int data[N][2];
15*404b540aSrobert static int INCR, NTHR, CHUNK;
16*404b540aSrobert 
clean_data(void)17*404b540aSrobert static void clean_data (void)
18*404b540aSrobert {
19*404b540aSrobert   memset (data, -1, sizeof (data));
20*404b540aSrobert }
21*404b540aSrobert 
test_data(void)22*404b540aSrobert static void test_data (void)
23*404b540aSrobert {
24*404b540aSrobert   int n, i, c, thr, iter, chunk;
25*404b540aSrobert 
26*404b540aSrobert   chunk = CHUNK;
27*404b540aSrobert   if (chunk == 0)
28*404b540aSrobert     chunk = N / INCR / NTHR;
29*404b540aSrobert 
30*404b540aSrobert   thr = iter = c = i = 0;
31*404b540aSrobert 
32*404b540aSrobert   for (n = 0; n < N; ++n)
33*404b540aSrobert     {
34*404b540aSrobert       if (i == 0)
35*404b540aSrobert 	{
36*404b540aSrobert 	  assert (data[n][0] == thr);
37*404b540aSrobert 	  assert (data[n][1] == iter);
38*404b540aSrobert 	}
39*404b540aSrobert       else
40*404b540aSrobert 	{
41*404b540aSrobert 	  assert (data[n][0] == -1);
42*404b540aSrobert 	  assert (data[n][1] == -1);
43*404b540aSrobert 	}
44*404b540aSrobert 
45*404b540aSrobert       if (++i == INCR)
46*404b540aSrobert 	{
47*404b540aSrobert 	  i = 0;
48*404b540aSrobert 	  if (++c == chunk)
49*404b540aSrobert 	    {
50*404b540aSrobert 	      c = 0;
51*404b540aSrobert 	      if (++thr == NTHR)
52*404b540aSrobert 		{
53*404b540aSrobert 		  thr = 0;
54*404b540aSrobert 		  ++iter;
55*404b540aSrobert 		}
56*404b540aSrobert 	    }
57*404b540aSrobert 	}
58*404b540aSrobert     }
59*404b540aSrobert }
60*404b540aSrobert 
set_data(long i,int thr,int iter)61*404b540aSrobert static void set_data (long i, int thr, int iter)
62*404b540aSrobert {
63*404b540aSrobert   int old;
64*404b540aSrobert   assert (i >= 0 && i < N);
65*404b540aSrobert   old = __sync_lock_test_and_set (&data[i][0], thr);
66*404b540aSrobert   assert (old == -1);
67*404b540aSrobert   old = __sync_lock_test_and_set (&data[i][1], iter);
68*404b540aSrobert   assert (old == -1);
69*404b540aSrobert }
70*404b540aSrobert 
f_static_1(void * dummy)71*404b540aSrobert static void f_static_1 (void *dummy)
72*404b540aSrobert {
73*404b540aSrobert   int iam = omp_get_thread_num ();
74*404b540aSrobert   long s0, e0, i, count = 0;
75*404b540aSrobert   if (GOMP_loop_static_start (0, N, INCR, CHUNK, &s0, &e0))
76*404b540aSrobert     do
77*404b540aSrobert       {
78*404b540aSrobert 	for (i = s0; i < e0; i += INCR)
79*404b540aSrobert 	  set_data (i, iam, count);
80*404b540aSrobert 	++count;
81*404b540aSrobert       }
82*404b540aSrobert     while (GOMP_loop_static_next (&s0, &e0));
83*404b540aSrobert   GOMP_loop_end ();
84*404b540aSrobert }
85*404b540aSrobert 
test(void)86*404b540aSrobert static void test (void)
87*404b540aSrobert {
88*404b540aSrobert   clean_data ();
89*404b540aSrobert   GOMP_parallel_start (f_static_1, NULL, NTHR);
90*404b540aSrobert   f_static_1 (NULL);
91*404b540aSrobert   GOMP_parallel_end ();
92*404b540aSrobert   test_data ();
93*404b540aSrobert }
94*404b540aSrobert 
main()95*404b540aSrobert int main()
96*404b540aSrobert {
97*404b540aSrobert   omp_set_dynamic (0);
98*404b540aSrobert 
99*404b540aSrobert   NTHR = 5;
100*404b540aSrobert 
101*404b540aSrobert   INCR = 1, CHUNK = 0;	/* chunk = 360 / 5 = 72 */
102*404b540aSrobert   test ();
103*404b540aSrobert 
104*404b540aSrobert   INCR = 4, CHUNK = 0;	/* chunk = 360 / 4 / 5 = 18 */
105*404b540aSrobert   test ();
106*404b540aSrobert 
107*404b540aSrobert   INCR = 1, CHUNK = 4;	/* 1 * 4 * 5 = 20 -> 360 / 20 = 18 iterations.  */
108*404b540aSrobert   test ();
109*404b540aSrobert 
110*404b540aSrobert   INCR = 3, CHUNK = 4;	/* 3 * 4 * 5 = 60 -> 360 / 60 = 6 iterations.  */
111*404b540aSrobert   test ();
112*404b540aSrobert 
113*404b540aSrobert   return 0;
114*404b540aSrobert }
115