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