// RUN: %libomp-compile-and-run
#include <stdio.h>
#include <stdlib.h>
#include "omp_testsuite.h"
#include "omp_my_sleep.h"
#define CFSMAX_SIZE 1000
#define MAX_TIME 0.01
#ifdef SLEEPTIME
#undef SLEEPTIME
#define SLEEPTIME 0.0005
#endif
int test_omp_for_schedule_static()
{
int threads;
int i,lasttid;
int * tids;
int notout;
int maxiter;
int chunk_size;
int counter = 0;
int tmp_count=1;
int lastthreadsstarttid = -1;
int result = 1;
chunk_size = 7;
tids = (int *) malloc (sizeof (int) * (CFSMAX_SIZE + 1));
notout = 1;
maxiter = 0;
#pragma omp parallel shared(tids,counter)
{ /* begin of parallel*/
#pragma omp single
{
threads = omp_get_num_threads ();
} /* end of single */
} /* end of parallel */
if (threads < 2) {
omp_set_num_threads(2);
threads = 2;
}
fprintf (stderr,"Using an internal count of %d\nUsing a specified"
" chunksize of %d\n", CFSMAX_SIZE, chunk_size);
tids[CFSMAX_SIZE] = -1; /* setting endflag */
#pragma omp parallel shared(tids)
{ /* begin of parallel */
double count;
int tid;
int j;
tid = omp_get_thread_num ();
#pragma omp for nowait schedule(static,chunk_size)
for(j = 0; j < CFSMAX_SIZE; ++j) {
count = 0.;
#pragma omp flush(maxiter)
if (j > maxiter) {
#pragma omp critical
{
maxiter = j;
}
}
/*printf ("thread %d sleeping\n", tid);*/
while (notout && (count < MAX_TIME) && (maxiter == j)) {
#pragma omp flush(maxiter,notout)
my_sleep (SLEEPTIME);
count += SLEEPTIME;
printf(".");
}
#ifdef VERBOSE
if (count > 0.) printf(" waited %lf s\n", count);
#endif
/*printf ("thread %d awake\n", tid);*/
tids[j] = tid;
#ifdef VERBOSE
printf("%d finished by %d\n",j,tid);
#endif
} /* end of for */
notout = 0;
#pragma omp flush(maxiter,notout)
} /* end of parallel */
/**** analysing the data in array tids ****/
lasttid = tids[0];
tmp_count = 0;
for (i = 0; i < CFSMAX_SIZE + 1; ++i) {
/* If the work was done by the same thread increase tmp_count by one. */
if (tids[i] == lasttid) {
tmp_count++;
#ifdef VERBOSE
fprintf (stderr, "%d: %d \n", i, tids[i]);
#endif
continue;
}
/* Check if the next thread had has the right thread number. When finding
* threadnumber -1 the end should be reached.
*/
if (tids[i] == (lasttid + 1) % threads || tids[i] == -1) {
/* checking for the right chunk size */
if (tmp_count == chunk_size) {
tmp_count = 1;
lasttid = tids[i];
#ifdef VERBOSE
fprintf (stderr, "OK\n");
#endif
} else {
/* If the chunk size was wrong, check if the end was reached */
if (tids[i] == -1) {
if (i == CFSMAX_SIZE) {
fprintf (stderr, "Last thread had chunk size %d\n",
tmp_count);
break;
} else {
fprintf (stderr, "ERROR: Last thread (thread with"
" number -1) was found before the end.\n");
result = 0;
}
} else {
fprintf (stderr, "ERROR: chunk size was %d. (assigned"
" was %d)\n", tmp_count, chunk_size);
result = 0;
}
}
} else {
fprintf(stderr, "ERROR: Found thread with number %d (should be"
" inbetween 0 and %d).", tids[i], threads - 1);
result = 0;
}
#ifdef VERBOSE
fprintf (stderr, "%d: %d \n", i, tids[i]);
#endif
}
return result;
}
int main()
{
int i;
int num_failed=0;
for(i = 0; i < REPETITIONS; i++) {
if(!test_omp_for_schedule_static()) {
num_failed++;
}
}
return num_failed;
}