Original Post
I have been given c code for a multi-threaded black-scholes financial model. The code is below. In the code below there are a set of threads created and each thread is given seperate arguments to execute code. I need to modify this so that there is one main that initializes the thread_data_array so it does not depend on the number of threads. It can be initialized to an arbitrary number of elements like 25. This thread_data_array will need to store two additional variables: Allocated (1 if computed, 0 if not) and Result (holds final result computed by thread). Then a number of threads need to be spawned for execution. When a thread enters the Black-Scholes function it should try to lock the thread_data_array and check to see if an element requires computation (if Allocated is 0). If so, it should copy the data into the local thread_data variables, unlock the array, and execute. Once done executing, it should lock the array, write back the results and update the allocated variable, and unlock the array. I really do not know how to go about doing this. I am not looking for someone to do my assignment, but just looking for help. Any help is appreciated. I was told that there is not a lot of code that needs to be changed or added to the model below to accomplish the modifications. #include #include #include #include #ifndef Pi #define Pi 3.141592653589793238462643 #endif #define NUM_THREADS 7 char *messages[NUM_THREADS]; struct thread_data { int thread_id; char flag; double stock_price; double strike_price; double years; double rate_risk_free; double volatility; }; struct thread_data thread_data_array[NUM_THREADS]; double CND( double ); void *BlackScholes(void *threadarg) { int taskid; struct thread_data *my_data; double d1, d2; double S, X, T, r, v; char CallPutFlag; my_data = (struct thread_data *)threadarg; taskid = my_data->thread_id; CallPutFlag = my_data->flag; S = my_data->stock_price; X = my_data->strike_price; T = my_data->years; r = my_data->rate_risk_free; v = my_data->volatility; d1=(log(S/X)+(r+v*v/2)*T)/(v*sqrt(T)); d2=d1-v*sqrt(T); if(CallPutFlag == 'c') printf("Thread %d Price =%f\n", taskid, (S*CND(d1)-X * exp(-r*T)*CND(d2))); else if(CallPutFlag == 'p') printf("Thread %d Price =%f\n", taskid, (X*exp(-r * T) * CND(-d2) - S * CND(-d1))); pthread_exit(NULL); } // The cumulative normal distribution function double CND( double X ) { double L, K, w ; double const a1 = 0.31938153, a2 = -0.356563782, a3 = 1.781477937; double const a4 = -1.821255978, a5 = 1.330274429; L = fabs(X); K = 1.0 / (1.0 + 0.2316419 * L); w = 1.0 - 1.0 / sqrt(2 * Pi) * exp(-L *L / 2) * (a1 * K + a2 * K *K + a3 * pow(K,3) + a4 * pow(K,4) + a5 * pow(K,5)); if (X < 0 ){ w= 1.0 - w; } return w; } int main() { pthread_t threads[NUM_THREADS]; int *taskids[NUM_THREADS]; int rc, t; for(t=0;t<NUM_THREADS;t++) { thread_data_array[t].thread_id = t; thread_data_array[t].flag = 'c'; thread_data_array[t].stock_price = 15.0; thread_data_array[t].strike_price = 22.0; thread_data_array[t].years = ((double)rand() / ((double)RAND_MAX + (double)1.0))*15; thread_data_array[t].rate_risk_free = ((double)rand() / ((double)RAND_MAX + (double)1.0))*5; thread_data_array[t].volatility = ((double)rand() / ((double)RAND_MAX + (double)1.0))*1.0; printf("Creating thread %d\n", t); rc = pthread_create(&threads[t], NULL, BlackScholes, (void *) &thread_data_array[t]); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } for(t=0; t<NUM_THREADS; t++) { int ret, status; ret = pthread_join(threads[t], (void **)&status); if(ret != 0) { printf("pthread_join: ERROR: t=%d return code =%d\n", t, ret); exit(1); } printf("Joined thread_id = %d\n", t); } pthread_exit(NULL); return 0; }