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
      14  static int data[N][2];
      15  static int INCR, NTHR, CHUNK;
      16  
      17  static void clean_data (void)
      18  {
      19    memset (data, -1, sizeof (data));
      20  }
      21  
      22  static 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  
      61  static 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    
      71  static 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  
      86  static 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  
      95  int 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  }