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

#define NUM_ACCOUNTS 2
#define NUM_TRANSACTION 10
#define INIT_BALANCE 0


int main(int argc, char *argv[])
{
    int i;
    double start_time, final_time;

    /* Balance of account numbers 0 - (NUM_ACCOUNTS - 1) */
    long balance[NUM_ACCOUNTS] = {INIT_BALANCE, INIT_BALANCE};
    long balance_ser[NUM_ACCOUNTS]  = {INIT_BALANCE, INIT_BALANCE};

    int transaction[NUM_TRANSACTION] =
        {10, 20, 30, -40, -50, 80, -10, -50, 100, 90};

    /*
     * This part of the code is run in serial to get the correct result.
     * We will use this result to check with our multithreaded solution
     * even indexed (including 0) transaction goes to account 0,
     * odd indexed transaction goes to account 1
     */
    for(i=0; i < NUM_TRANSACTION ; i++) {
        balance_ser[i % 2] += transaction[i];
    }

    start_time = omp_get_wtime();

    /* Parallelized version */
    /*
     * Parallelized account balance update part,
     * we used 'omp atomic' to upadate, it is to avoid race condition
     */
    #pragma omp parallel for
    for(i=0; i < NUM_TRANSACTION ; i++) {
        #pragma omp atomic
        balance[i % 2] += transaction[i];
    }

    final_time = omp_get_wtime() - start_time;
    printf("Total time using omp atomic: %.10f\n", final_time);
    printf("Final account balance is following...\n");


    for( i=0; i < NUM_ACCOUNTS; i++) {
        printf("Account No. = %d, actual balance = %ld,"
               "correct balance should be %ld\n",
               i, balance[i], balance_ser[i]);
    }


    return 0;
}
