1// RUN: %libomp-compile-and-run
2#include <stdio.h>
3#include <stdlib.h>
4#include "omp_testsuite.h"
5#include "omp_my_sleep.h"
6
7#define CFSMAX_SIZE 1000
8#define MAX_TIME 0.01
9
10#ifdef SLEEPTIME
11#undef SLEEPTIME
12#define SLEEPTIME 0.0005
13#endif
14
15#define VERBOSE 0
16
17int test_omp_for_schedule_static_3()
18{
19 int threads;
20 int i,lasttid;
21
22 int * tids;
23 int * tids2;
24 int notout;
25 int maxiter;
26 int chunk_size;
27
28 int counter = 0;
29 int tmp_count=1;
30 int lastthreadsstarttid = -1;
31 int result = 1;
32 chunk_size = 7;
33
34 tids = (int *) malloc (size: sizeof (int) * (CFSMAX_SIZE + 1));
35 notout = 1;
36 maxiter = 0;
37
38 #pragma omp parallel shared(tids,counter)
39 { /* begin of parallel*/
40 #pragma omp single
41 {
42 threads = omp_get_num_threads ();
43 } /* end of single */
44 } /* end of parallel */
45
46 /* Ensure that at least two threads are created */
47 if (threads < 2) {
48 omp_set_num_threads(2);
49 threads = 2;
50 }
51 fprintf (stderr,format: "Using an internal count of %d\nUsing a"
52 " specified chunksize of %d\n", CFSMAX_SIZE, chunk_size);
53 tids[CFSMAX_SIZE] = -1; /* setting endflag */
54
55 #pragma omp parallel shared(tids)
56 { /* begin of parallel */
57 double count;
58 int tid;
59 int j;
60
61 tid = omp_get_thread_num ();
62
63 #pragma omp for nowait schedule(static,chunk_size)
64 for(j = 0; j < CFSMAX_SIZE; ++j) {
65 count = 0.;
66 #pragma omp flush(maxiter)
67 if (j > maxiter) {
68 #pragma omp critical
69 {
70 maxiter = j;
71 }
72 }
73 /*printf ("thread %d sleeping\n", tid);*/
74 while (notout && (count < MAX_TIME) && (maxiter == j)) {
75 #pragma omp flush(maxiter,notout)
76 my_sleep (SLEEPTIME);
77 count += SLEEPTIME;
78 printf(format: ".");
79 }
80#ifdef VERBOSE
81 if (count > 0.) printf(format: " waited %lf s\n", count);
82#endif
83 /*printf ("thread %d awake\n", tid);*/
84 tids[j] = tid;
85#ifdef VERBOSE
86 printf(format: "%d finished by %d\n",j,tid);
87#endif
88 } /* end of omp parallel for */
89
90 notout = 0;
91 #pragma omp flush(maxiter,notout)
92 } /* end of parallel */
93
94 /**** analysing the data in array tids ****/
95
96 lasttid = tids[0];
97 tmp_count = 0;
98
99 for (i = 0; i < CFSMAX_SIZE + 1; ++i) {
100 /* If the work was done by the same thread
101 increase tmp_count by one. */
102 if (tids[i] == lasttid) {
103 tmp_count++;
104#ifdef VERBOSE
105 fprintf (stderr, format: "%d: %d \n", i, tids[i]);
106#endif
107 continue;
108 }
109
110 /* Check if the next thread had has the right thread number.
111 * When finding threadnumber -1 the end should be reached.
112 */
113 if (tids[i] == (lasttid + 1) % threads || tids[i] == -1) {
114 /* checking for the right chunk size */
115 if (tmp_count == chunk_size) {
116 tmp_count = 1;
117 lasttid = tids[i];
118#ifdef VERBOSE
119 fprintf (stderr, format: "OK\n");
120#endif
121 } else {
122 /* If the chunk size was wrong, check if the end was reached */
123 if (tids[i] == -1) {
124 if (i == CFSMAX_SIZE) {
125 fprintf (stderr, format: "Last thread had chunk size %d\n",
126 tmp_count);
127 break;
128 } else {
129 fprintf (stderr, format: "ERROR: Last thread (thread with"
130 " number -1) was found before the end.\n");
131 result = 0;
132 }
133 } else {
134 fprintf (stderr, format: "ERROR: chunk size was %d. (assigned"
135 " was %d)\n", tmp_count, chunk_size);
136 result = 0;
137 }
138 }
139 } else {
140 fprintf(stderr, format: "ERROR: Found thread with number %d (should be"
141 " inbetween 0 and %d).", tids[i], threads - 1);
142 result = 0;
143 }
144#ifdef VERBOSE
145 fprintf (stderr, format: "%d: %d \n", i, tids[i]);
146#endif
147 }
148
149 /* Now we check if several loop regions in one parallel region have the
150 * same logical assignment of chunks to threads. We use the nowait
151 * clause to increase the probability to get an error. */
152
153 /* First we allocate some more memory */
154 free (ptr: tids);
155 tids = (int *) malloc (sizeof (int) * LOOPCOUNT);
156 tids2 = (int *) malloc (sizeof (int) * LOOPCOUNT);
157
158 #pragma omp parallel
159 {
160 {
161 int n;
162 #pragma omp for schedule(static) nowait
163 for (n = 0; n < LOOPCOUNT; n++) {
164 if (LOOPCOUNT == n + 1 )
165 my_sleep(SLEEPTIME);
166
167 tids[n] = omp_get_thread_num();
168 }
169 }
170 {
171 int m;
172 #pragma omp for schedule(static) nowait
173 for (m = 1; m <= LOOPCOUNT; m++) {
174 tids2[m-1] = omp_get_thread_num();
175 }
176 }
177 }
178
179 for (i = 0; i < LOOPCOUNT; i++)
180 if (tids[i] != tids2[i]) {
181 fprintf (stderr, "Chunk no. %d was assigned once to thread %d and"
182 " later to thread %d.\n", i, tids[i],tids2[i]);
183 result = 0;
184 }
185
186 free (ptr: tids);
187 free (ptr: tids2);
188 return result;
189}
190
191int main()
192{
193 int i;
194 int num_failed=0;
195
196 for (i = 0; i < REPETITIONS; i++) {
197 if(!test_omp_for_schedule_static_3()) {
198 num_failed++;
199 }
200 }
201 return num_failed;
202}
203

source code of openmp/runtime/test/worksharing/for/omp_for_schedule_static_3.c