| /* Test that all loop iterations are touched. This doesn't verify | |
| scheduling order, merely coverage. */ | |
| /* { dg-require-effective-target sync_int_long } */ | |
| #include <omp.h> | |
| #include <string.h> | |
| #include <assert.h> | |
| #include "libgomp_g.h" | |
| #define N 10000 | |
| static int S, E, INCR, CHUNK, NTHR; | |
| static int data[N]; | |
| static void clean_data (void) | |
| { | |
| memset (data, -1, sizeof (data)); | |
| } | |
| static void test_data (void) | |
| { | |
| int i, j; | |
| for (i = 0; i < S; ++i) | |
| assert (data[i] == -1); | |
| for (j = 0; i < E; ++i, j = (j + 1) % INCR) | |
| if (j == 0) | |
| assert (data[i] != -1); | |
| else | |
| assert (data[i] == -1); | |
| for (; i < N; ++i) | |
| assert (data[i] == -1); | |
| } | |
| static void set_data (long i, int val) | |
| { | |
| int old; | |
| assert (i >= 0 && i < N); | |
| old = __sync_lock_test_and_set (data+i, val); | |
| assert (old == -1); | |
| } | |
| #define TMPL_1(sched) \ | |
| static void f_##sched##_1 (void *dummy) \ | |
| { \ | |
| int iam = omp_get_thread_num (); \ | |
| long s0, e0, i; \ | |
| if (GOMP_loop_##sched##_start (S, E, INCR, CHUNK, &s0, &e0)) \ | |
| do \ | |
| { \ | |
| for (i = s0; i < e0; i += INCR) \ | |
| set_data (i, iam); \ | |
| } \ | |
| while (GOMP_loop_##sched##_next (&s0, &e0)); \ | |
| GOMP_loop_end (); \ | |
| } \ | |
| static void t_##sched##_1 (void) \ | |
| { \ | |
| clean_data (); \ | |
| GOMP_parallel_start (f_##sched##_1, NULL, NTHR); \ | |
| f_##sched##_1 (NULL); \ | |
| GOMP_parallel_end (); \ | |
| test_data (); \ | |
| } | |
| TMPL_1(static) | |
| TMPL_1(dynamic) | |
| TMPL_1(guided) | |
| #define TMPL_2(sched) \ | |
| static void f_##sched##_2 (void *dummy) \ | |
| { \ | |
| int iam = omp_get_thread_num (); \ | |
| long s0, e0, i; \ | |
| while (GOMP_loop_##sched##_next (&s0, &e0)) \ | |
| { \ | |
| for (i = s0; i < e0; i += INCR) \ | |
| set_data (i, iam); \ | |
| } \ | |
| GOMP_loop_end_nowait (); \ | |
| } \ | |
| static void t_##sched##_2 (void) \ | |
| { \ | |
| clean_data (); \ | |
| GOMP_parallel_loop_##sched##_start \ | |
| (f_##sched##_2, NULL, NTHR, S, E, INCR, CHUNK); \ | |
| f_##sched##_2 (NULL); \ | |
| GOMP_parallel_end (); \ | |
| test_data (); \ | |
| } | |
| TMPL_2(static) | |
| TMPL_2(dynamic) | |
| TMPL_2(guided) | |
| static void test (void) | |
| { | |
| t_static_1 (); | |
| t_dynamic_1 (); | |
| t_guided_1 (); | |
| t_static_2 (); | |
| t_dynamic_2 (); | |
| t_guided_2 (); | |
| } | |
| int main() | |
| { | |
| omp_set_dynamic (0); | |
| NTHR = 4; | |
| S = 0, E = N, INCR = 1, CHUNK = 4; | |
| test (); | |
| S = 0, E = N, INCR = 2, CHUNK = 4; | |
| test (); | |
| S = 1, E = N-1, INCR = 1, CHUNK = 5; | |
| test (); | |
| S = 1, E = N-1, INCR = 2, CHUNK = 5; | |
| test (); | |
| S = 2, E = 4, INCR = 1, CHUNK = 1; | |
| test (); | |
| S = 0, E = N, INCR = 1, CHUNK = 0; | |
| t_static_1 (); | |
| t_static_2 (); | |
| S = 1, E = N-1, INCR = 1, CHUNK = 0; | |
| t_static_1 (); | |
| t_static_2 (); | |
| return 0; | |
| } |