reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
// 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

#define VERBOSE 0

int test_omp_for_schedule_static_3()
{
  int threads;
  int i,lasttid;

  int * tids;
  int * tids2;
  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 */

  /* Ensure that at least two threads are created */
  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 omp parallel 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
  }

  /* Now we check if several loop regions in one parallel region have the
   * same logical assignement of chunks to threads. We use the nowait
   * clause to increase the probability to get an error. */

  /* First we allocate some more memmory */
  free (tids);
  tids = (int *) malloc (sizeof (int) * LOOPCOUNT);
  tids2 = (int *) malloc (sizeof (int) * LOOPCOUNT);

  #pragma omp parallel
  {
    {
      int n;
      #pragma omp for schedule(static) nowait
      for (n = 0; n < LOOPCOUNT; n++) {
        if (LOOPCOUNT == n + 1 )
          my_sleep(SLEEPTIME);

        tids[n] = omp_get_thread_num();
      }
    }
    {
      int m;
      #pragma omp for schedule(static) nowait
      for (m = 1; m <= LOOPCOUNT; m++) {
        tids2[m-1] = omp_get_thread_num();
      }
    }
  }

  for (i = 0; i < LOOPCOUNT; i++)
  if (tids[i] != tids2[i]) {
    fprintf (stderr, "Chunk no. %d was assigned once to thread %d and"
      " later to thread %d.\n", i, tids[i],tids2[i]);
    result = 0;
  }

  free (tids);
  free (tids2);
  return result;
}

int main()
{
  int i;
  int num_failed=0;

  for (i = 0; i < REPETITIONS; i++) {
    if(!test_omp_for_schedule_static_3()) {
      num_failed++;
    }
  }
  return num_failed;
}