Sun Studio 12: Thread Analyzer User's Guide

2.4.3.1 Fixing Bugs in omp_prime.c

Here's how to fix the bug in omp_prime.c. See 2.1.1 Complete Listing of omp_prime.c for a complete file listing.

Move lines 45 and 46 into a critical section in order to remove the data-race between the read from total on line 45 and the write to total on line 46. The critical section protects the two lines and prevents the data-race. Here is the corrected code:

42      #pragma omp parallel for         .
43      for (i = 2; i < N; i++) {
44          if ( is_prime(i) ) {
                 #pragma omp critical

                 {          
 45                 primes[total] = i;
 46                 total++;
                 }
 47          }
 48      }

Note that the addition of a single critical section also fixes two other data races in omp_prime.c. It fixes the data-race on prime[] at line 45, as well as the data-race on total at line 46. The fourth data-race, between a read from pflag[] from line 18 and a write to pflag[] from line 21, is actually a benign race because it does not lead to incorrect results. It is not essential to fix benign data-races.

You could also move lines 45 and 46 into a critical section as follows, but this change fails to correct the program:

42      #pragma omp parallel for         .
43      for (i = 2; i < N; i++) {
44          if ( is_prime(i) ) {
                 #pragma omp critical
                 {          
45                 primes[total] = i;
                 }
                 #pragma omp critical
                 {

46                 total++;
                 }
47          }
48      }

The critical sections around lines 45 and 46 get rid of the data-race because the threads are not using any exclusive locks to control their accesses to total. The critical section around line 46 ensures that the computed value of total is correct. However, the program is still incorrect. Two threads may update the same element of primes[] using the same value of total. Moreover, some elements in primes[] may not be assigned a value at all.