#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
//pi = 4/1 - 4/3 + 4/5 - 4/7 + 4/9 - 4/11....


void Usage(void){
	printf("some random alpha software\n");
	printf("pi3 [-t threads] [-v/-h]\n");
}

void *worker(void *tid){
	uint32_t prec = 4294967295;
	uint32_t num1 = 1;
	double pi = 0;
	double tmp = 0;
	double odd_num = 1;

	while(num1 < prec){
		//num1++;
		tmp = 4/odd_num;
		if(num1%2 == 0){
			tmp *= -1;
		}
		pi += tmp;

		odd_num += 2;
		num1++;
	}
	//printf("
	//printf("%lf\n", pi);
	pthread_exit(NULL);
}

int main(int argc, char **argv){
	if(argc > 3){
		Usage();
		exit(1);
	}
	uint32_t n1 = 0;
	uint32_t n2 = 0;
	uint32_t Threads = 0;
	uint32_t Tcount = 0;
	uint32_t options[4];
	double totaltime = 0;
	struct timeval starttime;
	struct timeval endtime;

	(void)memset((void *)options, '\0', sizeof(uint32_t) * 4 );
	if(argc > 1){
		for(n1=1; n1<argc; n1++){
			if( strcmp( (const char *)argv[n1], "-h") == 0){
				options[0] = n1+1;
				if(n1+1 > argc-1)
					n2 = 1;
			}
			if( strcmp( (const char *)argv[n1], "-v") == 0){
				options[1] = n1+1;
				if(n1+1 > argc-1)
					n2 = 1;
			}
			if( strcmp( (const char *)argv[n1], "-t") == 0){
				options[2] = n1+1;
				if(n1+1 > argc-1)
					n2 = 1;
			}
		}
		if(n2){
			Usage();
			exit(1);
		}
	}else{
		Usage();
		exit(1);
	}
	if(options[0] != 0){
		Usage();
		exit(1);
	}
	if(options[1] != 0){
		Usage();
		exit(1);
	}
	if(options[2] != 0){
		Threads = atoi(argv[options[2]]);
		if(Threads == 0){
			printf("Error: Threads input is not a valid number!\n");
			exit(1);
		}
	}

	pthread_t *Actions_thread_ptrs = (pthread_t *)malloc(sizeof(pthread_t) * Threads );
	printf("Launching %u Action threads.\n", Threads);
	gettimeofday(&starttime, NULL);
	for(Tcount = 0; Tcount < Threads; Tcount++){
		if(pthread_create(&Actions_thread_ptrs[Tcount], NULL, worker, NULL) != 0){
			printf("Error: pthread_create failed for action thread: %d !\n", Tcount);
			printf("\tExiting!\n");
			free(Actions_thread_ptrs);
			exit(1);
		}
	}

	for(Tcount=0; Tcount < Threads; Tcount++){
		if(pthread_join(Actions_thread_ptrs[Tcount], NULL) != 0){
			printf("Error: pthread_join failed for action thread: %d !\n", Tcount);
			printf("\tExiting!\n");
			free(Actions_thread_ptrs);
			exit(1);
		}
	}
	gettimeofday(&endtime, NULL);
	totaltime = ((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
	free(Actions_thread_ptrs);
	//printf("Done.\n");
	printf("Total: %lfsecs\n", totaltime);
	printf("\t%lfsec/thread\n", totaltime/Threads);
	printf("Done.\n");
	return 0;
}
