/*
 * A simple program for permitting concurrent updates to a bank account by
 * multiple people.
 *
 */

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

const int delay_factor = 100;
unsigned int *seeds;

int get_next_transaction_val(int p)
{
    int val;
    usleep(delay_factor);
#pragma omp critical
    val = rand_r(&seeds[p]);
    return (val % 1500) - 300;
}

int main()
{
    int i,j;
    int num_people          = 2;
    int num_transactions    = 1000;
    float balance           = 500.0;

    /* initialize seeds for generating trasactions */
    seeds = malloc(sizeof(*seeds)*num_people);

    double time1 = omp_get_wtime();


#pragma omp parallel private(i,j)
    {
#pragma omp for nowait
        for (i = 0; i < num_people; i++) seeds[i] = i;
#pragma omp for collapse(2) reduction(+:balance) schedule(static)
        for (i = 0; i < num_people; i++) {
            for (j = 0; j < num_transactions; j++) {
                float x  = (float)get_next_transaction_val(i);
                balance += x;
            }
        }
    }

    double time2 = omp_get_wtime();

    printf("Final balance = %.2f\n", balance);
    printf("Total time = %.5lf ms.\n", (time2-time1)*1000.0);

    return 0;
}
