/*
** Pthreads Hello World
** Copyright Rolf Riesen 2008
**
*/
#include <stdio.h>
#include <stdlib.h>	/* For strtol(), exit(), malloc() */
#include <unistd.h>	/* For getopt() */
#include <errno.h>	/* For perror() */
#include <pthread.h>	/* For pthread_*() */


/* Constants */
#define DEFAULT_NUM_THREADS	(4)
#define FALSE			(0)
#define TRUE			(1)


/* Local functions */
static void *hello_func(void *arg);
static void usage(char *pname);



int
main(int argc, char *argv[])
{

extern char *optarg;
int ch, error;

int nproc;
int i, rc;
int *ranks;
pthread_t *thread;


 
    /* Initialize some variables */
    nproc= DEFAULT_NUM_THREADS;		/* Default number of threads */
    opterr= 0;	/* Don't let getopt print an error msg */
    error= FALSE;


    while ((ch= getopt(argc, argv, "p:")) != EOF)   {
	switch (ch)   {
	    case 'p':
		nproc= strtol(optarg, (char **)NULL, 0);
		if (nproc < 1)   {
		    error= TRUE;
		}
		break;
	    default:
		error= TRUE;
	}
    }

    if (error)   {
	usage(argv[0]);
	exit(-1);
    }


    /* Allocate storage for the thread handles */
    thread= (pthread_t *)malloc(nproc * sizeof(pthread_t));
    if (thread == NULL)   {
	fprintf(stderr, "Out of memory!\n");
	exit(-1);
    }

    /* Allocate storage for the thread arguments */
    ranks= (int *)malloc(nproc * sizeof(int));
    if (ranks == NULL)   {
	fprintf(stderr, "Out of memory!\n");
	exit(-1);
    }

    printf("main() This program is running with %d threads\n", nproc);

    for (i= 0; i < nproc; i++)   {
	ranks[i]= i;
	rc= pthread_create(&thread[i], NULL, hello_func, (void *)&ranks[i]);
	if (rc != 0)   {
	    perror("pthread_create() failed");
	    exit(-1); 
	}
    }

    for (i= 0; i < nproc; i++)   {
	pthread_join(thread[i], NULL);
    }

    printf("main() Done\n");

    return 0; 

}  /* end of main() */



static void *
hello_func(void *arg)
{

int my_rank;


    my_rank= *(int *)arg;
    printf("Rank %3d: initialized and ready\n", my_rank);
    return NULL;

}  /* end of hello_func() */



static void
usage(char *pname)
{

    fprintf(stderr, "Usage: %s [-p num]\n", pname);
    fprintf(stderr, "           -p num   Create num threads\n");
    fprintf(stderr, "                    Default is %d.\n", DEFAULT_NUM_THREADS);

}  /* end of usage() */
