1  /* Test that all loop iterations are touched.  This doesn't verify 
       2     scheduling order, merely coverage.  */
       3  
       4  /* { dg-require-effective-target sync_int_long } */
       5  
       6  #include <omp.h>
       7  #include <string.h>
       8  #include <assert.h>
       9  #include "libgomp_g.h"
      10  
      11  
      12  #define N 10000
      13  static int S, E, INCR, CHUNK, NTHR;
      14  static int data[N];
      15  
      16  static void clean_data (void)
      17  {
      18    memset (data, -1, sizeof (data));
      19  }
      20  
      21  static void test_data (void)
      22  {
      23    int i, j;
      24  
      25    for (i = 0; i < S; ++i)
      26      assert (data[i] == -1);
      27  
      28    for (j = 0; i < E; ++i, j = (j + 1) % INCR)
      29      if (j == 0)
      30        assert (data[i] != -1);
      31      else
      32        assert (data[i] == -1);
      33  
      34    for (; i < N; ++i)
      35      assert (data[i] == -1);
      36  }
      37  
      38  static void set_data (long i, int val)
      39  {
      40    int old;
      41    assert (i >= 0 && i < N);
      42    old = __sync_lock_test_and_set (data+i, val);
      43    assert (old == -1);
      44  }
      45    
      46  
      47  #define TMPL_1(sched)						\
      48  static void f_##sched##_1 (void *dummy)				\
      49  {								\
      50    int iam = omp_get_thread_num ();				\
      51    long s0, e0, i;						\
      52    if (GOMP_loop_##sched##_start (S, E, INCR, CHUNK, &s0, &e0))	\
      53      do								\
      54        {								\
      55  	for (i = s0; i < e0; i += INCR)				\
      56  	  set_data (i, iam);					\
      57        }								\
      58      while (GOMP_loop_##sched##_next (&s0, &e0));		\
      59    GOMP_loop_end ();						\
      60  }								\
      61  static void t_##sched##_1 (void)				\
      62  {								\
      63    clean_data ();						\
      64    GOMP_parallel_start (f_##sched##_1, NULL, NTHR);		\
      65    f_##sched##_1 (NULL);						\
      66    GOMP_parallel_end ();						\
      67    test_data ();							\
      68  }
      69  
      70  TMPL_1(static)
      71  TMPL_1(dynamic)
      72  TMPL_1(guided)
      73  
      74  #define TMPL_2(sched)					\
      75  static void f_##sched##_2 (void *dummy)			\
      76  {							\
      77    int iam = omp_get_thread_num ();			\
      78    long s0, e0, i;					\
      79    while (GOMP_loop_##sched##_next (&s0, &e0))		\
      80      {							\
      81        for (i = s0; i < e0; i += INCR)			\
      82  	set_data (i, iam);				\
      83      }							\
      84    GOMP_loop_end_nowait ();				\
      85  }							\
      86  static void t_##sched##_2 (void)			\
      87  {							\
      88    clean_data ();					\
      89    GOMP_parallel_loop_##sched##_start			\
      90      (f_##sched##_2, NULL, NTHR, S, E, INCR, CHUNK);	\
      91    f_##sched##_2 (NULL);					\
      92    GOMP_parallel_end ();					\
      93    test_data ();						\
      94  }
      95  
      96  TMPL_2(static)
      97  TMPL_2(dynamic)
      98  TMPL_2(guided)
      99  
     100  static void test (void)
     101  {
     102    t_static_1 ();
     103    t_dynamic_1 ();
     104    t_guided_1 ();
     105    t_static_2 ();
     106    t_dynamic_2 ();
     107    t_guided_2 ();
     108  }
     109  
     110  int main()
     111  {
     112    omp_set_dynamic (0);
     113  
     114    NTHR = 4;
     115  
     116    S = 0, E = N, INCR = 1, CHUNK = 4;
     117    test ();
     118  
     119    S = 0, E = N, INCR = 2, CHUNK = 4;
     120    test ();
     121  
     122    S = 1, E = N-1, INCR = 1, CHUNK = 5;
     123    test ();
     124  
     125    S = 1, E = N-1, INCR = 2, CHUNK = 5;
     126    test ();
     127  
     128    S = 2, E = 4, INCR = 1, CHUNK = 1;
     129    test ();
     130  
     131    S = 0, E = N, INCR = 1, CHUNK = 0;
     132    t_static_1 ();
     133    t_static_2 ();
     134  
     135    S = 1, E = N-1, INCR = 1, CHUNK = 0;
     136    t_static_1 ();
     137    t_static_2 ();
     138  
     139    return 0;
     140  }