yeban
3/12/2010 - 4:42 PM

threads.c

/*
 * =====================================================================================
 *
 *       Filename:  threads.c
 *
 *    Description:  Familiarising with pthreads.
 *
 *        Version:  1.0
 *        Created:  Thursday 11 March 2010 01:25:12  IST
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Anurag Priyam (yeban), anurag08priyam@gmail.com
 *        Company:  IIT Kharagpur
 *
 * =====================================================================================
 */

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>//for EXIT_FAILURE

#define MAX_N 100
#define MAX_NUMBER 500

typedef struct {
    int n, p, segment;
    int *array;
} arguments;

void bubble_sort(int *array, int size){
    int i, j, temp;
    for(i = 1; i < size; i++){
	for(j = 0; j < size - i; j++){
	    if(array[j] > array[j+1]){
		temp = array[ j ];
		array[ j ] = array[ j + 1 ];
		array[ j + 1 ] = temp;
	    }
	}
    }
}

//perform sorting on each segment by calling
//bubble_sort with the right arguments, i.e,
//pointer to the start of each segment and the size of the segment
void* sort( void *args ){
    arguments *args_sort = ( arguments* )args;

    long tid;
    int first = 0;
    for( tid = 0; tid < args_sort->p; tid++ ){
	bubble_sort( args_sort->array + first, args_sort->segment );
	first += args_sort->segment;
    }
}

int main(){
    arguments args;
    int error;

    //seed the random number generator
    srandom( time( NULL ) );

    //get n and p
    args.n = random() % MAX_N + 1;
    printf( "Enter a factor of %d: ", args.n );
    scanf( "%d", &args.p );

    //compute segment size
    args.segment = args.n/args.p;

    //populate the array
    int i;
    args.array = calloc( args.n, sizeof( int ) );
    for( i = 0; i < args.n; i++ ){
	args.array[ i ] = random() % MAX_NUMBER + 1;
    }

    //thread creation variables
    pthread_t threads[ args.p ];
    pthread_attr_t attr;
    long tid;

    //set thread detached attribute
    pthread_attr_init( &attr );
    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
    
    //create the threads
    for( tid = 0; tid < args.p; tid++ ){
	if( error = pthread_create( &threads[ tid ], &attr, sort, ( void* )&args ) ){
	    printf( "Creating thread: %s\n", strerror( error ) );
	    exit( EXIT_FAILURE );
	}
    }

    //free attr and
    //wait for the threads to complete
    pthread_attr_destroy( &attr );
    for( tid = 0; tid < args.p; tid++ ){
	if( error = pthread_join( threads[ tid ], NULL ) ){
	    printf( "Joining thread: %s\n", strerror( error ) );
	    exit( EXIT_FAILURE );
	}
    }

    //the segments will have been sorted
    //display each sorted segment
    int first = 0, last = args.segment;
    for( tid = 0; tid < args.p; tid++ ){
	printf( "Sorted segment of thread %d\n", tid );
	for(i = first; i < last; i++ ){
	    printf( "%d ", args.array[ i ] );
	}
	printf( "\n" );
	first = last; last += args.segment;
    }

    free( args.array );
}