/*
 * 03-race-condition.c  —  The SAME sum, done WRONG (a live data race)
 * Session 03 · 2311CSC501J Parallel Processing
 *
 * WHAT THIS SHOWS  (run it 4 or 5 times!)
 *   This is 02-parallel-sum.c with ONE thing removed: the reduction clause.
 *   Now every thread reads and writes the SAME shared variable `sum` at the
 *   same time. The statement
 *
 *       sum += a[i];
 *
 *   is not one step — it is three: READ sum, ADD a[i], WRITE sum back. When
 *   two threads do this at once they can read the same old value, both add to
 *   it, and one write clobbers the other. Updates get LOST. This is a
 *   DATA RACE (a.k.a. race condition).
 *
 *   The tell-tale symptom: the answer is (a) wrong — smaller than N — and
 *   (b) DIFFERENT almost every run. Correct code gives the same answer every
 *   time; racy code gives you whatever the threads happened to interleave into.
 *
 * THE FIX
 *   See 02-parallel-sum.c: add reduction(+:sum). (Heavier hammers like
 *   #pragma omp critical or #pragma omp atomic around the update would also
 *   make it correct, but they serialize every add and kill performance —
 *   reduction is the right tool for a sum.)
 *
 * HOW TO COMPILE & RUN
 *       gcc -fopenmp 03-race-condition.c -o race
 *       ./race ; ./race ; ./race        # run it several times, watch it change
 *
 *   macOS (Apple clang): clang -Xpreprocessor -fopenmp -lomp 03-race-condition.c -o race
 *   Or paste into OnlineGDB / godbolt.org (add -fopenmp) and press Run a few times.
 */

#include <stdio.h>
#include <omp.h>

#define N 10000000    /* 10 million elements, all 1s -> correct total is N */

int main(void) {
    static int a[N];
    long sum = 0;

    #pragma omp parallel for
    for (int i = 0; i < N; i++) {
        a[i] = 1;
    }

    /* BUG ON PURPOSE: no reduction. Many threads hammer the shared `sum`. */
    #pragma omp parallel for
    for (int i = 0; i < N; i++) {
        sum += a[i];              /* RACE: read-modify-write on shared `sum` */
    }

    printf("Result   = %ld   (expected %d)\n", sum, N);
    printf("Run me again — the wrong answer usually CHANGES between runs.\n");
    printf("That instability is the signature of a data race. Fix: 02-parallel-sum.c\n");
    return 0;
}
