Oracle® Solaris Studio 12.4: Thread Analyzer User's Guide

Exit Print View

Updated: December 2014
 
 

Source Code for prime_pthr.c

This section shows source code for prime_pthr.c as follows:

  1  /*
  2   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All Rights Reserved.
  3   * @(#)prime_pthr.c 1.4 (Oracle) 10/03/26
  4   */
  5
  6  #include <stdio.h>
  7  #include <math.h>
  8  #include <pthread.h>
  9
 10  #define THREADS 4
 11  #define N 10000
 12
 13  int primes[N];
 14  int pflag[N];
 15  int total = 0;
 16
 17  int is_prime(int v)
 18  {
 19      int i;
 20      int bound = floor(sqrt(v)) + 1;
 21
 22      for (i = 2; i < bound; i++) {
 23          /* no need to check against known composites */
 24          if (!pflag[i])
 25              continue;
 26          if (v % i == 0) {
 27              pflag[v] = 0;
 28              return 0;
 29          }
 30      }
 31      return (v > 1);
 32  }
 33
 34  void *work(void *arg)
 35  {
 36      int start;
 37      int end;
 38      int i;
 39
 40      start = (N/THREADS) * (*(int *)arg);
 41      end = start + N/THREADS;
 42      for (i = start; i < end; i++) {
 43          if ( is_prime(i) ) {
 44              primes[total] = i;
 45              total++;
 46          }
 47      }
 48      return NULL;
 49  }
 50
 51  int main(int argn, char **argv)
 52  {
 53      int i;
 54      pthread_t tids[THREADS-1];
 55
 56      for (i = 0; i < N; i++) {
 57          pflag[i] = 1;
 58      }
 59
 60      for (i = 0; i < THREADS-1; i++) {
 61          pthread_create(&tids[i], NULL, work, (void *)&i);
 62      }
 63
 64      i = THREADS-1;
 65      work((void *)&i);
 66
 67      for (i = 0; i < THREADS-1; i++) {
 68          pthread_join(tids[i], NULL);
 69      }
 70
 71      printf("Number of prime numbers between 2 and %d: %d\n",
 72             N, total);
 73
 74      return 0;
 75  }

Effect of Data Races in prime_omp.c and prime_pthr.c

When there is a race condition in the code, the order of memory accesses is non-deterministic so the computation gives different results from run to run. The correct answer in the prime_omp and prime_pthr programs is 1229.

You can compile and run the examples so you can see that the execution of prime_omp or prime_pthr produces incorrect and inconsistent results because of the data races in the code.

In the following example, type the commands at the prompt to compile and run the prime_omp program:

% cc -xopenmp=noopt -o prime_omp prime_omp.c -lm
%
% ./prime_omp
Number of prime numbers between 2 and 10000: 1229
% ./prime_omp
Number of prime numbers between 2 and 10000: 1228
% ./prime_omp
Number of prime numbers between 2 and 10000: 1180

In the following example, type the commands at the prompt to compile and run the prime_pthr program:

% cc -mt -o prime_pthr prime_pthr.c -lm
%
% ./prime_pthr
Number of prime numbers between 2 and 10000: 1140
% ./prime_pthr
Number of prime numbers between 2 and 10000: 1122
% ./prime_pthr
Number of prime numbers between 2 and 10000: 1141

Notice the inconsistency of the results of the three runs of each program. You might need to run the programs more than three times to see inconsistent results.

Next you instrument the code and create experiments so you can find where the data races are occurring.