/****************************************/
/*      	Includes                */
/****************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pvm3.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/param.h>
#include <limits.h>
#include <netdb.h>
#include <assert.h>

/****************************************/
/*	Tests Modules			*/
/****************************************/

#define NUMBER_OF_TESTS 	107	/* number of test modules 			*/
#define NUMBER_TEST_DIGITS	3 	/* maximum number of digits of NUMBER_OF_TESTS	*/

#define	NOT_YET_PROCESSED	0	/*						*/
#define	NOT_POSSIBLE		-3	/*						*/
#define	NOT_COMPLETED		-2	/*		Test Status			*/
#define PASSED			1	/*						*/
#define FAILED			-1	/*						*/

/* flag structure */
typedef struct {
	int	perform;				/* Do we perform the test or not	*/
	int 	after_hosts;				/* Number of Hosts after completion 	*/
		}test_flag;

#define ALL_HOSTS		999			/* I want all hosts for that test	*/
#define	ALL_ARCHS		666			/* I want one host of each architecture */

/* Test_module */
typedef struct{
	
	char            description[60];                /* Description of the test module	*/

	test_flag	flag;				/* Flags				*/
	int		num_req_hosts;			/* Number of hosts required		*/
	short		status;				/* Status of the test module		*/
	short		(*proc_master)();		/* Pointer to the master function	*/
	void 		(*proc_slave)();		/* Pointer to the slave function	*/
		}test_module;

typedef test_module module_array[NUMBER_OF_TESTS]; 	/* Array of modules	 		*/
module_array *masters;					/* Pointer to an array of modules	*/

/****************************************/
/*	Host Pool and descriptor	*/
/****************************************/

#define MAX_HOST		20			/* Max number of hosts in the config.	*/
#define MAX_HOST_NAME_LENGTH	20			/* Max length of a host name		*/
#define VERSION_SLAVE		"version_slave"		/* Name of the version slave		*/

#define	TIMEOUT_MESSAGE		60			/* number of 1 sec. retries 		*/
#define	TIMEOUT_ADD_DELETE	30			/* number of 1 sec. retries		*/
#define TIMEOUT_KILL		30			/* number of 1 sec. retries             */
#define BUSY_LOOP_PERF		50000			/* number of iterations od the busy loop*/
							/* ( busy loop for timing tests )	*/

char	*hostpool[MAX_HOST];				/* array of non-master hosts		*/
char	*hostarch[MAX_HOST];				/* array of architectures		*/
char	*diff_arch[MAX_HOST];				/* array of distinct architectures	*/

/****************************************/
/*          INPUT / OUTPUT		*/ 
/****************************************/

#define MAX_LINE_LENGTH         80			/* Max length of a line in input file	*/

#define COMBOS_PREFIX           "all_combinations :"	/*					*/
#define HOST_PREFIX             "config :"		/* 	General options prefix		*/
#define OUTFILE_PREFIX          "outfile :"		/*					*/
#define	OUTFILE_MAX_LENGTH	40			/*					*/

#define MAX_LENGTH_PREFIX       "max_length :"		/*					*/
#define START_LENGTH_PREFIX     "start_length :"	/*	tests 45 & 46 prefix		*/
#define INCR_PREFIX             "incr :"		/*					*/


#define LENGTH_PREFIX		"messages_length :"	/*					*/
#define	NUM_PREFIX		"num_messages :"	/*		tests 48 -> 107		*/
#define	FUNNELING_PREFIX	"funneling_proc :"	/*		prefix			*/	
#define TIMING_TOTAL_PREFIX	"total_timing :"	/*					*/
#define TIMING_AVERAGE_PREFIX	"average_timing :"	/*					*/

#define ALL_TESTS_PREFIX		"all_tests :"		/*					*/
#define	ALL_MESSAGING_PREFIX		"all_messaging :"	/*	Subsets of tests		*/
#define ALL_ROUTINE_PREFIX		"all_routine :"		/*		prefixes		*/
#define ALL_FUNNEL_NODATA_PREFIX	"all_funnel_nodata :"	/*					*/
#define ALL_FUNNEL_DATA_PREFIX		"all_funnel_data :"	/*					*/
#define ALL_HEAD_NODATA_PREFIX		"all_head_nodata :"	/*					*/
#define ALL_HEAD_DATA_PREFIX		"all_head_data :"	/*					*/
#define ALL_TRIANGLE_NODATA_PREFIX	"all_triangle_nodata :"	/*					*/
#define ALL_TRIANGLE_DATA_PREFIX	"all_triangle_data :"	/*					*/
#define ALL_PERF_PREFIX			"all_perf :"		/*					*/

#define	OUT45			"/tmp/output_45.dat"	/*	Output file for test #45	*/
#define OUT46			"/tmp/output_46.dat"	/*	Output file for test #46	*/

FILE	*outfile;
FILE	*out45;
FILE	*out46;

/****************************************/
/*          MESSAGES TAGS		*/
/****************************************/

#define ACKNOLEDGE		9			/* tag for acknoledging slave start		*/
#define VERSION_TAG		10			/* tag of message returning version number	*/
#define JOINED			11			/* tag acknoledging a group joining		*/
#define SIGNAL			12			/* tag acknowledging of a interrupt signal	*/ 
#define	BYE			13			/* tag telling to the slave to exit		*/
#define	TEST_VALUE		14			/* tag for value coherency			*/
#define	TEST_CAST		15			/* tag for broadcast test			*/
#define	TEST_BARRIER		16			/* tag for barrier test				*/
#define	TEST_REDUCE		17			/* tag for reduce test				*/
#define	TEST_GATHER		18			/* tag for gather test				*/
#define	TEST_SCATTER		19			/* tag for scatter test				*/
#define TEST_MCAST		20			/* tag for mcast test				*/
#define	LATENCY			21			/* tag for latency measurement messages		*/
#define BANDWIDTH		22			/* tag for bandwidth measurements messages	*/
#define HEAD_HEAD		23			/* tag for head-head test			*/
#define	TRIANGLE		24			/* tag for triangle test			*/
#define	FUNNELING		25			/* tag for funneling				*/
#define	NOTIFY			26			/* tag for notify test				*/
#define	ENDLESS			99			/* to let the slaves do non-busy waiting	*/

/****************************************/
/*          MISCELLENAOUS		*/
/****************************************/

#define GROUP_NAME		"Testgrp"		/* group name					*/
#define SNOOZ                   1       		/* maximum delay accepted for pvm_config races  */
#define TEST_SLAVE		"pvm_test_slave"	/* Generic slave name				*/
#define	HIGH_LEVEL		1			/* Exit code for term()				*/
#define	OK_LEVEL		2			/* End code for term()				*/
#define SEC_TRECV		10			/* Number of seconds timeout for the trecv test */
#define	SEC_NRECV		10			/* Number of seconds timeout for the nrecv test */

/*********************************************/
/* PARAMETERS FOR THE LATENCY-BANDWIDTH TEST */
/*********************************************/

#define	TRIALS			10			/* Trials fo average latency/bandwidth comput.	*/
#define	TIME_ELAPSED		(t2.tv_sec-t1.tv_sec+(t2.tv_usec-t1.tv_usec)*1.E-6)

int	max_size		;			/*						*/
int	start_size		;			/*  parameters for tests #45 and #46   		*/
int	incr			;			/*						*/

#define MAX_SIZE_DEFAULT	1000			/*						*/
#define START_SIZE_DEFAULT	100			/*   Default parameters for tests #45 amd #46	*/
#define INCR_DEFAULT		100			/* 						*/

#define MAX_MESSAGE_LENGTH	100000			/* Maximum allowable message length		*/

int	all_combos		;			/* Do we try all the architectures combinations */

#define	ALL_COMBOS_DEFAULT	0			/*	default parameter for all_combos	*/

/****************************************************/
/* PARAMETERS FOR THE GENERAL MESSAGE-PASSING TESTS */
/****************************************************/

#define EMPTY			0			/* Empty Messages				*/
#define NOT_EMPTY		1			/* Not empty messages				*/
#define MCAST			0			/* Use of pvm_mcast()				*/
#define SEND			1			/* Use of pvm_send()-pvm_recv() 		*/
#define PSEND			2			/* Use of pvm_psend()-pvm_precv() if possible	*/

int     num_messages            ;                       /*   Number of messages for tests mes_pass      */
int     messages_length         ;                       /*   Length of these messages                   */
int	timing_average		;			/*   Do we time the average communication time	*/	
int	timing_total		;			/*   Do we time the total communication time	*/

#define	NUM_MESSAGES_DEFAULT	10			/*						*/
#define MESSAGES_LENGTH_DEFAULT	100			/*						*/
#define FUNNELING_DEFAULT	4			/*	Default parameters			*/
#define	TIMING_AVERAGE_DEFAULT  0			/*						*/
#define	TIMING_TOTAL_DEFAULT	0			/*						*/

/****************************************************/
/* PARAMETERS FOR THE SUBSETS OF TESTS		    */
/****************************************************/

int	all_tests		;
int	all_messaging		;
int	all_routine		;
int	all_funnel_nodata	;
int	all_funnel_data		;
int	all_head_nodata		;
int	all_head_data		;
int	all_triangle_nodata	;
int	all_triangle_data	;
int	all_perf		;

#define	ALL_TESTS_DEFAULT		0
#define	ALL_MESSAGING_DEFAULT		0
#define	ALL_ROUTINE_DEFAULT		0
#define	ALL_FUNNEL_NODATA_DEFAULT	0
#define ALL_FUNNEL_DATA_DEFAULT		0
#define ALL_HEAD_NODATA_DEFAULT		0
#define ALL_HEAD_DATA_DEFAULT		0
#define ALL_TRIANGLE_NODATA_DEFAULT	0
#define	ALL_TRIANGLE_DATA_DEFAULT	0
#define	ALL_PERF_DEFAULT		0
