The function called by pthread_create breaks when a value is assigned to the structure that was passed to it

Advertisement

I am novice on C. I have a small program that is intended to solve find the product of a large 2d matrix point with itself using pthread. Now, when the function assigned to the pthread is called and the structure is passed as a variable, the program breaks and stops working. I do not really know what is going wrong. Here's the code:

This is the main function.

 int main() { int rc; int threadcount = 1; char filename[100]; //patch to enable console printing in eclipse setvbuf(stdout, NULL, _IONBF, 0); do { prompt_for_fileName(filename); if (filename[0] == 'Q' || filename[0] == 'q') { puts("Program ended"); return 0; } //read thread count read_threadcount(&threadcount); //initialize matrices matrix_def matrix = initialize_matrix(filename); //get the dimension of sub-matrices int dfRow = (int) floor(matrix.NROWS / threadcount); pthread_t threads[threadcount]; pthread_arg pthreadargs[threadcount]; for (int i = 0; i < threadcount; i++) { int startRow = i * dfRow; int endRow = ((i + 1) == threadcount) ? matrix.NROWS : (startRow + dfRow) - 1; //we're subtracting one because its zero based. //create a structure that we'll passed to the array. pthread_arg arg = { matrix.NROWS, matrix.NCOLS, startRow, endRow, 0.0, NULL, NULL }; arg.data = matrix.data; arg.result_set = create_result_memory(matrix.NCOLS); fprintf(stderr, "before %p\n", arg.result_set); //push arg into array. pthreadargs[i] = arg; rc = pthread_create(&threads[i], NULL, compute_dot_product, (void *) &arg); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } /* Last thing that main() should do */ pthread_exit(NULL); puts("Completed processing."); double totalTime = 0.0; for (int z = 0; z < threadcount; z++) { pthread_arg ar = pthreadargs[z]; printf("Thread %d took %g to process %d rows and %d columns.\n", z, ar.execution_time, ar.endz - ar.start, ar.col); totalTime += ar.execution_time; } printf( "It took the total time of %g, to compute the dot product of the matrices.\n", totalTime); //free memory free(matrix.data); for (int k = 0; k < threadcount; k++) { free(pthreadargs[k].data); free(pthreadargs[k].result_set); } } while (filename[0] != 'Q' || filename[0] != 'q'); } 

This is the function called by the pthread

 void * compute_dot_product(void * inputArgs) { double startTime, endTime; pthread_arg * args = inputArgs; /*Compute the dimension of the result matrix*/ int col, row, start, endz; col = args->col; start = args->start; endz = args->endz; row = endz - start; fprintf(stderr, "after %p\n", args->result_set); //create a pointer to the two array double **arr1 = args->data; double **arr2 = arr1; //begin the computation int x; startTime = seconds(); //calculate the dot product the two matrices. for (x = 0; x < col; x++) { double colProduct = 0.0; for (int y = start; y < endz; y++) { colProduct += arr1[y][x] * arr2[y][x]; } //The code breaks here. args->result_set[x] = colProduct; } endTime = seconds(); double diff = endTime - startTime; args->execution_time = diff; return (void *) 4; } 

Here are my structure definitions

 typedef struct { int NROWS; /*for m rows*/ int NCOLS; /*for n columns*/ double ** data; } matrix_def; typedef struct { double execution_time; matrix_def matrix; } compute_result; typedef struct{ int row; int col; int start; int endz; double execution_time; double **data; double *result_set; } pthread_arg; 

Any help will be appreciated, as I am not very sure of the formula. Thank you

The answer

arg leaves the scope before pthread is executed. Change your call to

  rc = pthread_create(&threads[i], NULL, compute_dot_product, (void *) &pthreadargs[i]); 

You will also need pthread_join before going out, in case the threads are not finished.

edit

1) Replace your pthread_exit with

 int rv; for (i = 0; i < threadcount; ++i) pthread_join(thread[i], &rv); 

You typically call pthread_exit inside a thread (like compute_dot_product) as an abnormal output. This is a possible reason for breaking your program.

2) When you exit, I do not know how you assigned your memory, but it's a potential area where your code could be broken. If you have given your brief

 matrix.data = malloc(sizeof(double*) * matrix.NROWS); matrix.data[0] = malloc(sizeof(double) * matrix.NROWS * matrix.NCOLS); for (i = 1; i < matrix.NROWS; ++i) matrix.data[i] = matrix.data[i - 1] + matrix.NCOLS; 

Then you should release as

 free(matrix.data[0]); free(matrix.data); 

If you have assigned each row individually, release all rows before releasing matrix.data.

3) Since matrix.data was released, pthreadargs [k] .data should not be released because it indicates the same memory area that has already been released.