/****************************************/
/*	message_passing.c		*/
/*	tests for :			*/
/*		head-head		*/
/*		triangle		*/
/*		funneling		*/
/****************************************/

#include "pvm_test.h"

/********************************/
/*	HEAD TO HEAD		*/
/********************************/

/*	MASTER	*/

short head_head(args,host,is_empty,send_mode,route,data_format)
char	**args;
int	host;
int	is_empty;
int	send_mode;
int	route;
int 	data_format;
{
int	i;
int	tid;
int	narch;
int	info,ack;
int	*inbuf;
int	*outbuf;
int	nhost;
int	count;
struct	pvmhostinfo *hostp;
int	atid,atag,alen;
struct  timeval t1,t2;
double  Total_time=0;
double  Average_time;

inbuf = (int *)malloc(sizeof(int)*messages_length);
outbuf = (int *)malloc(sizeof(int)*messages_length);
/** Check if options possible **/
info = pvm_config(&nhost,&narch,&hostp);
if (info <0)
	{
	fprintf(outfile,"\tpvm_config() : Failed with error %d\n",info); 
	return -1;
	}
if (narch >1)
	{
	if (data_format != PvmDataDefault)
		return NOT_POSSIBLE;
	if (send_mode != SEND)
		return NOT_POSSIBLE;
	}
fprintf(outfile,"%s (%s ) <---> %s (%s )\n",
	hostpool[0],hostarch[0],hostpool[host],hostarch[host]);
info = pvm_spawn(TEST_SLAVE,args,PvmTaskHost,hostpool[host],1,&tid);
if (info <1)
	{
	fprintf(outfile,"\tpvm_spawn() : Failed with error %d for host %s\n", 
		tid,hostpool[host]);
	return -1;
	}

info = pvm_initsend(PvmDataDefault);
if (info <0)
	{
	fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_pkint(&messages_length,1,1);
if (info <0)
	{
	fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_send(tid,ACKNOLEDGE);
if (info <0)
	{
	fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
		info,hostpool[host]);
	goto fail;
	}
ack = timeout_wait_message(tid,ACKNOLEDGE,host);
if (ack <0)
	goto fail;

info = pvm_recv(tid,ACKNOLEDGE);
if (info <0)
	{
	fprintf(outfile,"\tpvm_recv() : Failed with error %d for host %s\n",
		info,hostpool[host]);
	goto fail;
	}

info = pvm_setopt(PvmRoute,route);
if (info <0)
	{
	fprintf(outfile,"\tpvm_setopt() : Failed with error %d\n",info);
	goto fail;
	}	

if ((is_empty == EMPTY)&&(send_mode == SEND))
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for(i=0;i< num_messages;i++)
		{
		if ((info = pvm_initsend(data_format))<0)
			{
			fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n");
			goto fail;
			}
		if ((info = pvm_send(tid,HEAD_HEAD)) <0)
			{
			fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
				info,hostpool[host]);
			goto fail;
			}
		for (count=0;count<BUSY_LOOP_PERF;count++)
                	if (pvm_probe(tid,HEAD_HEAD)>0)
                        	break;
        	if (count== BUSY_LOOP_PERF)
                	{
	                fprintf(outfile,"\tTimeout expired from host %s\n",
       	                 	hostpool[host]);
                	goto fail;
                	}
		/*
		ack = timeout_wait_message(tid,HEAD_HEAD,host);
		if (ack <0)
			goto fail;
		*/
		if ((info = pvm_recv(tid,HEAD_HEAD))<0)
			{
			fprintf(outfile,"\tpvm_recv() : Failed with error %d for host %s\n",
				info,hostpool[host]);
			goto fail;
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
		Total_time = TIME_ELAPSED;
		fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
		Average_time = TIME_ELAPSED / ((double)num_messages);
		fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	pvm_kill(tid);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	return 1;

	}	
if ((is_empty == EMPTY)&&(send_mode == PSEND))
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for(i=0;i<num_messages;i++)
		{
		if ((info = pvm_psend(tid,HEAD_HEAD,outbuf,0,PVM_INT))<0)
			{
			fprintf(outfile,"\tpvm_psend() : Failed with error %d for host %s\n",
				info,hostpool[host]);
			goto fail;
			}
		for (count=0;count<BUSY_LOOP_PERF;count++)
                        if (pvm_probe(tid,HEAD_HEAD)>0)
                                break;
                if (count== BUSY_LOOP_PERF)
                        {
                        fprintf(outfile,"\tTimeout expired from host %s\n",
                                hostpool[host]);
                        goto fail;
                	}
		/*
                ack = timeout_wait_message(tid,HEAD_HEAD,host);
                if (ack <0)
                        goto fail;
		*/
		if ((info = pvm_precv(tid,HEAD_HEAD,inbuf,0,PVM_INT,&atid,&atag,&alen))<0)
			{
			fprintf(outfile,"\tpvm_precv() : Failed with error %d for host %s\n",
				info,hostpool[host]);
			goto fail;
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
        	Total_time = TIME_ELAPSED;
        	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
       		Average_time = TIME_ELAPSED / ((double)num_messages);
	        fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	pvm_kill(tid);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	return 1;
	}

/*	Here is_empty = NOT_EMPTY */
if (send_mode == PSEND)
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for(i=0;i<num_messages;i++)
		{
		if ((info = pvm_psend(tid,HEAD_HEAD,outbuf,messages_length,PVM_INT))<0)
			{
			fprintf(outfile,"\tpvm_psend() : Failed with error %d for host %s\n",
				info,hostpool[host]);
			goto fail;
			}
		for (count=0;count<BUSY_LOOP_PERF;count++)
                        if (pvm_probe(tid,HEAD_HEAD)>0)
                                break;
                if (count== BUSY_LOOP_PERF)
                        {
                        fprintf(outfile,"\tTimeout expired from host %s\n",
                                hostpool[host]);
                        goto fail;
                	}
		/*
                ack = timeout_wait_message(tid,HEAD_HEAD,host);
                if (ack <0)
                        goto fail;
		*/
		if ((info = pvm_precv(tid,HEAD_HEAD,inbuf,
			messages_length,PVM_INT,&atid,&atag,&alen))<0)
			{	
			fprintf(outfile,"\tpvm_precv() : Failed with error %d for host %s\n",
				info,hostpool[host]);
			goto fail;
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
        	Total_time = TIME_ELAPSED;
        	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
      		Average_time = TIME_ELAPSED / ((double)num_messages);
	        fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	pvm_kill(tid);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	return 1;
	}

/* 	Here send_mode == SEND and is_empty = NOT_EMPTY	*/
if (timing_total||timing_average)
	gettimeofday(&t1,NULL);
for(i=0;i<num_messages;i++)
	{
	if ((info = pvm_initsend(data_format))<0)
		{
		fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n");
		goto fail;
		}
	if ((info = pvm_pkint(outbuf,messages_length,1)) <0)
		{	
		fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
		goto fail;
		}
	if ((info = pvm_send(tid,HEAD_HEAD))<0)
		{
		fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
			info,hostpool[host]);
		goto fail;
		}
	for (count=0;count<BUSY_LOOP_PERF;count++)
                if (pvm_probe(tid,HEAD_HEAD)>0)
                        break;
        if (count== BUSY_LOOP_PERF)
                {
                fprintf(outfile,"\tTimeout expired from host %s\n",
                        hostpool[host]);
                goto fail;
                }
	/*
        ack = timeout_wait_message(tid,HEAD_HEAD,host);
        if (ack <0)
                goto fail;
	*/
	if ((info = pvm_recv(tid,HEAD_HEAD))<0)
		{
		fprintf(outfile,"\tpvm_recv() : Failed with error %d from host %s\n",
			info,hostpool[host]);
		goto fail;
		}
	if ((info = pvm_upkint(inbuf,messages_length,1))<0)
		{
		fprintf(outfile,"\tpvm_upkint() : Failed with error %d\n",info);
		goto fail;
		}
	}
if (timing_total||timing_average)
	gettimeofday(&t2,NULL);
if (timing_total)
	{
	Total_time = TIME_ELAPSED;
	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
	}
if (timing_average)
	{
	Average_time = TIME_ELAPSED / ((double)num_messages);
	fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
	}	
pvm_kill(tid);
pvm_setopt(PvmRoute,PvmAllowDirect);
return 1;

fail:
	pvm_setopt(PvmRoute,PvmAllowDirect);
	pvm_kill(tid);
	return -1;
	
}	

/*	SLAVE	*/
void head_head_slave(is_empty,send_mode,route,data_format)
int	is_empty;
int	send_mode;
int	route;
int	data_format;
{
int	*inbuf;
int	*outbuf;
int	atid,atag,alen;
int	length;

pvm_recv(pvm_parent(),ACKNOLEDGE);
pvm_upkint(&length,1,1);
inbuf = (int*)malloc(sizeof(int)*length);
outbuf = (int *)malloc(sizeof(int)*length);

pvm_initsend(PvmDataDefault);
pvm_send(pvm_parent(),ACKNOLEDGE);
pvm_setopt(PvmRoute,route);


if ((is_empty == EMPTY)&&(send_mode == SEND))
	{
	while(1)	
		{	
		pvm_recv(pvm_parent(),HEAD_HEAD);
		pvm_initsend(data_format);
		pvm_send(pvm_parent(),HEAD_HEAD);
		}
	}	
if ((send_mode == PSEND)&&(is_empty == EMPTY))
	{
	while(1)
		{
		pvm_precv(pvm_parent(),HEAD_HEAD,inbuf,0,PVM_INT,&atid,&atag,&alen);
		pvm_psend(pvm_parent(),HEAD_HEAD,outbuf,0,PVM_INT);
		}
	}
if (send_mode == PSEND)
	{	
	while(1)
		{
		pvm_precv(pvm_parent(),HEAD_HEAD,inbuf,length,PVM_INT,&atid,&atag,&alen);
		pvm_psend(pvm_parent(),HEAD_HEAD,outbuf,length,PVM_INT);
		}
	}
while(1)
	{
	pvm_recv(pvm_parent(),HEAD_HEAD);
	pvm_upkint(inbuf,length,1);
	pvm_initsend(data_format);
	pvm_pkint(outbuf,length,1);
	pvm_send(pvm_parent(),HEAD_HEAD);
	}
}



/********************************/
/*	TRIANGLE		*/
/********************************/

/*	MASTER	*/

short triangle(args,host1,host2,is_empty,send_mode,route,data_format)
char	**args;
int	host1;
int	host2;
int	is_empty;
int	send_mode;
int	route;
int 	data_format;
{
int	i;
int	tid1;
int	tid2;
int	narch;
int	info,ack;
int	*inbuf;
int	*outbuf;
int	you_are_the_first=1;
int	you_are_the_second=2;
int	nhost;
struct  timeval t1,t2;
double  Total_time=0;
double  Average_time;
int	count;
struct	pvmhostinfo *hostp;
int	atid,atag,alen;

inbuf = (int *)malloc(sizeof(int)*messages_length);
outbuf = (int *)malloc(sizeof(int)*messages_length);

/** Check if options possible **/
info = pvm_config(&nhost,&narch,&hostp);
if (info <0)
	{
	fprintf(outfile,"\tpvm_config() : Failed with error %d\n",info);
	return -1;
	}
if (narch >1)
	{
	if (data_format != PvmDataDefault)
		return NOT_POSSIBLE;
	if (send_mode != SEND)
		return NOT_POSSIBLE;
	}

fprintf(outfile,"%s (%s ) ---> %s (%s ) ---> %s (%s ) --->\n",
	hostpool[0],hostarch[0],
	hostpool[host1],hostarch[host1],
	hostpool[host2],hostarch[host2]);
info = pvm_spawn(TEST_SLAVE,args,PvmTaskHost,hostpool[host1],1,&tid1);
if (info <1)
	{
	fprintf(outfile,"\tpvm_spawn() : Failed with error %d for host %s\n",
		tid1,hostpool[host1]);
	return -1;
	}
info = pvm_spawn(TEST_SLAVE,args,PvmTaskHost,hostpool[host2],1,&tid2);
if (info <1)
	{
	fprintf(outfile,"\tpvm_spawn() : Failed with error %d for host %s\n",
		tid2,hostpool[host2]);
	pvm_kill(tid1);
	return -1;
	}
/*	First Slave */
info = pvm_initsend(PvmDataDefault);
if (info <0)
	{
	fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_pkint(&tid2,1,1);
if (info <0)
	{
	fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_send(tid1,ACKNOLEDGE);
if (info <0)
	{
	fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
		info,hostpool[host1]);
	goto fail;
	}
info = pvm_initsend(PvmDataDefault);
if (info <0)
	{
	fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_pkint(&you_are_the_first,1,1);
if (info <0)
	{
	fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_send(tid1,ACKNOLEDGE);
if (info <0)
	{
	fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
		info,hostpool[host1]);
	goto fail;
	}
info = pvm_initsend(PvmDataDefault);
if (info <0)
	{
	fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
        goto fail;
        }
info = pvm_pkint(&messages_length,1,1);
if (info <0)
        {
        fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
        goto fail;
        }
info = pvm_send(tid1,ACKNOLEDGE);
if (info <0)
        {
        fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
                info,hostpool[host1]);
        goto fail;
        }


/*	Second Slave */
info = pvm_initsend(PvmDataDefault);
if (info <0)
	{
	fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_pkint(&tid1,1,1);
if (info <0)
	{
	fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_send(tid2,ACKNOLEDGE);
if (info <0)
	{
	fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
		info,hostpool[host1]);
	goto fail;
	}
info = pvm_initsend(PvmDataDefault);
if (info <0)
	{
	fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_pkint(&you_are_the_second,1,1);
if (info <0)
	{
	fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
	goto fail;
	}
info = pvm_send(tid2,ACKNOLEDGE);
if (info <0)
	{
	fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
		info,hostpool[host1]);
	goto fail;
	}
info = pvm_initsend(PvmDataDefault);
if (info <0)
	{
        fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
        goto fail;
        }
info = pvm_pkint(&messages_length,1,1);
if (info <0)
        {
        fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
        goto fail;
        }
info = pvm_send(tid2,ACKNOLEDGE);
if (info <0)
        {
        fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
                info,hostpool[host1]);
        goto fail;
        }

/* Acknoledgements */

ack = timeout_wait_message(tid1,ACKNOLEDGE,host1);
if (ack <0)
	goto fail;

info = pvm_recv(tid1,ACKNOLEDGE);
if (info <0)
	{
	fprintf(outfile,"\tpvm_recv() : Failed with error %d for host %s\n",
		info,hostpool[host1]);
	goto fail;
	}

ack = timeout_wait_message(tid2,ACKNOLEDGE,host2);
if (ack <0)
	goto fail;

info = pvm_recv(tid2,ACKNOLEDGE);
if (info <0)
	{
	fprintf(outfile,"\tpvm_recv() : Failed with error %d for host %s\n",
		info,hostpool[host2]);
	goto fail;
	}
/*	Test Body */

info = pvm_setopt(PvmRoute,route);
if (info <0)
	{
	fprintf(outfile,"\tpvm_setopt() : Failed with error %d\n",info);
	goto fail;
	}	

if ((is_empty == EMPTY)&&(send_mode == SEND))
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for(i=0;i< num_messages;i++)
		{
		if ((info = pvm_initsend(data_format))<0)
			{
			fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n");
			goto fail;
			}
		if ((info = pvm_send(tid1,TRIANGLE)) <0)
			{
			fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
				info,hostpool[host1]);
			goto fail;
			}
		for (count=0;count<BUSY_LOOP_PERF;count++)
                        if (pvm_probe(tid2,TRIANGLE)>0)
                                break;
                if (count== BUSY_LOOP_PERF)
                        {
                        fprintf(outfile,"\tTimeout expired from host %s\n",
                                hostpool[host2]);
                        goto fail;
			}
		/*
                ack = timeout_wait_message(tid2,TRIANGLE,host2);
                if (ack <0)
                        goto fail;
		*/
		if ((info = pvm_recv(tid2,TRIANGLE))<0)
			{
			fprintf(outfile,"\tpvm_recv() : Failed with error %d for host %s\n",
				info,hostpool[host2]);
			goto fail;
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
        	Total_time = TIME_ELAPSED;
	        fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
		Average_time = TIME_ELAPSED / ((double)num_messages);
       	 	fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	pvm_kill(tid1);
	pvm_kill(tid2);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	return 1;

	}	
if ((is_empty == EMPTY)&&(send_mode == PSEND))
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for(i=0;i<num_messages;i++)
		{
		if ((info = pvm_psend(tid1,TRIANGLE,outbuf,0,PVM_INT))<0)
			{
			fprintf(outfile,"\tpvm_psend() : Failed with error %d for host %s\n",
				info,hostpool[host1]);
			goto fail;
			}
		for (count=0;count<BUSY_LOOP_PERF;count++)
                        if (pvm_probe(tid2,TRIANGLE)>0)
                                break;
                if (count== BUSY_LOOP_PERF)
                        {
                        fprintf(outfile,"\tTimeout expired from host %s\n",
                                hostpool[host2]);
                        goto fail;
                        }
		/*
		ack = timeout_wait_message(tid2,TRIANGLE,host2);
                if (ack <0)
                        goto fail;
		*/
		if ((info = pvm_precv(tid2,TRIANGLE,inbuf,0,PVM_INT,&atid,&atag,&alen))<0)
			{
			fprintf(outfile,"\tpvm_precv() : Failed with error %d for host %s\n",
				info,hostpool[host2]);
			goto fail;
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
	        Total_time = TIME_ELAPSED;
       		fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
        	Average_time = TIME_ELAPSED / ((double)num_messages);
        	fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	pvm_kill(tid1);
        pvm_kill(tid2);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	return 1;
	}

/*	Here is_empty = NOT_EMPTY */
if (send_mode == PSEND)
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for(i=0;i<num_messages;i++)
		{
		if ((info = pvm_psend(tid1,TRIANGLE,outbuf,messages_length,PVM_INT))<0)
			{
			fprintf(outfile,"\tpvm_psend() : Failed with error %d for host %s\n",
				info,hostpool[host1]);
			goto fail;
			}
		for (count=0;count<BUSY_LOOP_PERF;count++)
                        if (pvm_probe(tid2,TRIANGLE)>0)
                                break;
                if (count== BUSY_LOOP_PERF)
                        {
                        fprintf(outfile,"\tTimeout expired from host %s\n",
                                hostpool[host2]);
                        goto fail;
                        }
		/*
		ack = timeout_wait_message(tid2,TRIANGLE,host2);
                if (ack <0)
                        goto fail;
		*/
		if ((info = pvm_precv(tid2,TRIANGLE,inbuf,
			messages_length,PVM_INT,&atid,&atag,&alen))<0)
			{	
			fprintf(outfile,"\tpvm_precv() : Failed with error %d for host %s\n",
				info,hostpool[host2]);
			goto fail;
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
        	Total_time = TIME_ELAPSED;
        	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
	        Average_time = TIME_ELAPSED / ((double)num_messages);
       		fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	pvm_kill(tid1);
        pvm_kill(tid2);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	return 1;
	}

/* 	Here send_mode == SEND and is_empty = NOT_EMPTY	*/
if (timing_total||timing_average)
	gettimeofday(&t1,NULL);
for(i=0;i<num_messages;i++)
	{
	if ((info = pvm_initsend(data_format))<0)
		{
		fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n");
		goto fail;
		}
	if ((info = pvm_pkint(outbuf,messages_length,1)) <0)
		{	
		fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
		goto fail;
		}
	if ((info = pvm_send(tid1,TRIANGLE))<0)
		{
		fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
			info,hostpool[host1]);
		goto fail;
		}
	for (count=0;count<BUSY_LOOP_PERF;count++)
                        if (pvm_probe(tid2,TRIANGLE)>0)
                                break;
                if (count== BUSY_LOOP_PERF)
                        {
                        fprintf(outfile,"\tTimeout expired from host %s\n",
                                hostpool[host2]);
                        goto fail;
                        }
	/*
	ack = timeout_wait_message(tid2,TRIANGLE,host2);
        if (ack <0)
                goto fail;
	*/
	if ((info = pvm_recv(tid2,TRIANGLE))<0)
		{
		fprintf(outfile,"\tpvm_recv() : Failed with error %d from host %s\n",
			info,hostpool[host2]);
		goto fail;
		}
	if ((info = pvm_upkint(inbuf,messages_length,1))<0)
		{
		fprintf(outfile,"\tpvm_upkint() : Failed with error %d\n",info);
		goto fail;
		}
	}
if (timing_total||timing_average)
	gettimeofday(&t2,NULL);
if (timing_total)
	{
	Total_time = TIME_ELAPSED;
	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
	}
if (timing_average)
	{
	Average_time = Total_time / ((double)num_messages);
	fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
	}
pvm_kill(tid1);
pvm_kill(tid2);
pvm_setopt(PvmRoute,PvmAllowDirect);
return 1;

fail:
	pvm_kill(tid1);
	pvm_kill(tid2);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	return -1;
	
}	

/*	SLAVE	*/
void triangle_slave(is_empty,send_mode,route,data_format)
int	is_empty;
int	send_mode;
int	route;
int	data_format;
{
int	*inbuf;
int	*outbuf;
int	rank,to,from,tidother;
int	atid,atag,alen;
int	length;

pvm_recv(pvm_parent(),ACKNOLEDGE);
pvm_upkint(&tidother,1,1);
pvm_recv(pvm_parent(),ACKNOLEDGE);
pvm_upkint(&rank,1,1);
pvm_recv(pvm_parent(),ACKNOLEDGE);
pvm_upkint(&length,1,1);

inbuf = (int *)malloc(sizeof(int)*length);
outbuf = (int *)malloc(sizeof(int)*length);

if (rank == 1)
	{
	to=tidother;	
	from = pvm_parent();
	}
else
	{
	to = pvm_parent();
	from = tidother;
	}
pvm_initsend(PvmDataDefault);
pvm_send(pvm_parent(),ACKNOLEDGE);

pvm_setopt(PvmRoute,route);

if ((is_empty == EMPTY)&&(send_mode == SEND))
	{
	while(1)
		{	
		pvm_recv(from,TRIANGLE);
		pvm_initsend(data_format);
		pvm_send(to,TRIANGLE);
		}
	}	
if ((send_mode == PSEND)&&(is_empty == EMPTY))
	{
	while(1)
		{
		pvm_precv(from,TRIANGLE,inbuf,0,PVM_INT,&atid,&atag,&alen);
		pvm_psend(to,TRIANGLE,outbuf,0,PVM_INT);
		}
	}
if (send_mode == PSEND)
	{	
	while(1)
	{
		pvm_precv(from,TRIANGLE,inbuf,length,PVM_INT,&atid,&atag,&alen);
		pvm_psend(to,TRIANGLE,outbuf,length,PVM_INT);
		}
	}
while(1)
	{
	pvm_recv(from,TRIANGLE);
	pvm_upkint(inbuf,length,1);
	pvm_initsend(data_format);
	pvm_pkint(outbuf,length,1);
	pvm_send(to,TRIANGLE);
	}
}


/********************************/
/*      FUNNELING		*/
/********************************/

/*      MASTER 	*/

short funneling(args,array_of_index,length,is_empty,send_mode,route,data_format)
char    **args;
int     *array_of_index;
int	length;
int     is_empty;
int     send_mode;
int     route;
int     data_format;
{
int     i,j;
int     *tid;
int     narch;
int     info,ack;
int     *inbuf;
int     *outbuf;
int     *effective_array_of_index;
int	number_of_process;
int	nhost;
struct	pvmhostinfo *hostp;
struct  timeval t1,t2;
double  Total_time=0;
double  Average_time;
int	count;
int	atid,atag,alen;

inbuf = (int *)malloc(sizeof(int)*messages_length);
outbuf = (int *)malloc(sizeof(int)*messages_length);

number_of_process = (*masters)[atoi(args[0])-1].num_req_hosts;
tid = (int *)malloc(number_of_process*sizeof(int));
effective_array_of_index=(int *)malloc(number_of_process*sizeof(int));
/** Check if options possible **/
info = pvm_config(&nhost,&narch,&hostp);
if (info <0)
	{
	fprintf(outfile,"\tpvm_config() : \
		Failed with error %d\n",info);
	free(tid);
	free(effective_array_of_index);	
	return -1;
	}
if (narch >1)
	{
	if (data_format != PvmDataDefault)
		{
		free(effective_array_of_index);
		free(tid);
		return NOT_POSSIBLE;
		}	
	if ((send_mode != SEND)&&(send_mode != MCAST))
		{
		free(effective_array_of_index);
		free(tid);
		return NOT_POSSIBLE;
		}
	}
for (i=0;i<length;i++)
	effective_array_of_index[i] = array_of_index[i];
for (i=length;i<number_of_process;i++)
		effective_array_of_index[i]=array_of_index[i% length];

fprintf(outfile,"%s (%s )\n",
        hostpool[0],hostarch[0]);
for (i=1;i<number_of_process;i++)
	fprintf(outfile,"\t\t ---> %s (%s )\n",
		hostpool[effective_array_of_index[i]],
		hostarch[effective_array_of_index[i]]);

for (i=1;i<number_of_process;i++)
	{
	info = pvm_spawn(TEST_SLAVE,args,PvmTaskHost,
		hostpool[effective_array_of_index[i]],1,&(tid[i]));
	if (info <1)
		{
		fprintf(outfile,"\tpvm_spawn() : Failed with error %d for host %s\n",
			tid[i],hostpool[effective_array_of_index[i]]);
		goto fail;
		}
	info = pvm_initsend(PvmDataDefault);
	if (info <0)
		{
		fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
		goto fail;
		}
	info = pvm_pkint(&messages_length,1,1);
	if (info <0)
		{
		fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
		goto fail;
		}
	info = pvm_send(tid[i],ACKNOLEDGE);
	if (info <0)
		{
		fprintf(outfile,"\tpvm_send() : Failed with error %d on host %s\n",
			info,hostpool[effective_array_of_index[i]]);
		goto fail;
		}
	ack = timeout_wait_message(tid[i],ACKNOLEDGE,effective_array_of_index[i]);
	if (ack<0)
		goto fail;

	info = pvm_recv(tid[i],ACKNOLEDGE);
	if (info <0)
		{
		fprintf(outfile,"\tpvm_recv() : Failed with error %d for host %s\n",
			info,hostpool[effective_array_of_index[i]]);
		goto fail;	
		}
	}

info = pvm_setopt(PvmRoute,route);
if (info <0)
	{
	fprintf(outfile,"\tpvm_setopt() : Failed with error %d\n",info);
	goto fail;
	}

if ((is_empty == EMPTY)&&(send_mode == SEND))
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for (j=0;j<num_messages;j++)
		{
		for (i=1;i<number_of_process;i++)
			{
			if ((info = pvm_initsend(data_format)) <0)
				{
				fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
				goto fail;
				}
			if ((info = pvm_send(tid[i],FUNNELING))<0)
				{
				fprintf(outfile,"\tpvm_send() : Failed with error %d for host %s\n",
					info,hostpool[effective_array_of_index[i]]);
				goto fail;
				}
			}
		for (i=1;i<number_of_process;i++)
			{
			for (count=0;count<BUSY_LOOP_PERF;count++)
                        	if (pvm_probe(-1,FUNNELING)>0)
                               		break;
                	if (count== BUSY_LOOP_PERF)
                        	{
                        	fprintf(outfile,"\tTimeout expired \n");
                        	goto fail;
                        	}
			/*
			ack = timeout_wait_message(-1,FUNNELING,-1);
                	if (ack <0)
                        	goto fail;
			*/
			if ((info = pvm_recv(-1,FUNNELING))<0)
				{	
				fprintf(outfile,"\tpvm_recv() : Failed with erro %d\n",info);
				goto fail;
				}
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
        	Total_time = TIME_ELAPSED;
	        fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
        	Average_time = TIME_ELAPSED / ((double)num_messages);
	        fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	for (j=1;j<number_of_process;j++)
		pvm_kill(tid[j]);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	free(tid);
	free(effective_array_of_index);
	return 1;
	}

if ((is_empty == EMPTY)&&(send_mode == MCAST))
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for (j=0;j<num_messages;j++)
		{
		if ((info = pvm_initsend(data_format))<0)
			{
			fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
			goto fail;
			}
		if ((info = pvm_mcast(tid+1,number_of_process-1,FUNNELING))<0)
			{
			fprintf(outfile,"\tpvm_mcast() : Failed with error %d\n",info);
			goto fail;
			}
		for (i=1;i<number_of_process;i++)
			{
			for (count=0;count<BUSY_LOOP_PERF;count++)
                                if (pvm_probe(-1,FUNNELING)>0)
                                        break;
                        if (count== BUSY_LOOP_PERF)
                                {
                                fprintf(outfile,"\tTimeout expired\n");
                                goto fail;
                                }
			/*
			ack = timeout_wait_message(-1,FUNNELING,-1);
                        if (ack <0)
                                goto fail;
			*/
			if ((info = pvm_recv(-1,FUNNELING))<0)
				{
				fprintf(outfile,"\tpvm_recv() : Failed with error %d\n",info);
				goto fail;
				}
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
	        Total_time = TIME_ELAPSED;
        	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
	        Average_time = TIME_ELAPSED / ((double)num_messages);
	        fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	for (j=1;j<number_of_process;j++)
		pvm_kill(tid[j]);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	free(tid);
	free(effective_array_of_index);
	return 1;
	}

if ((is_empty == EMPTY)&&(send_mode = PSEND))
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for (j=0;j<num_messages;j++)
		{
		for (i=1;i<number_of_process;i++)
			if ((info = pvm_psend(tid[i],FUNNELING,outbuf,0,PVM_INT))<0)
				{
				fprintf(outfile,"\tpvm_psend() : Failed with error %d for host %s\n",
					info,hostpool[effective_array_of_index[i]]);
				goto fail;
				}
		for (i=1;i<number_of_process;i++)
			{
			for (count=0;count<BUSY_LOOP_PERF;count++)
                                if (pvm_probe(-1,FUNNELING)>0)
                                        break;
                        if (count== BUSY_LOOP_PERF)
                                {
                                fprintf(outfile,"\tTimeout expired\n");
                                goto fail;
                                }
			/*
			ack = timeout_wait_message(-1,FUNNELING,-1);
                        	if (ack <0)
                                	goto fail;
			*/
			if ((info = pvm_precv(-1,FUNNELING,inbuf,0,PVM_INT,&atid,&atag,&alen))<0)
				{
				fprintf(outfile,"\tpvm_precv() : Failed with error %d\n",info);
				goto fail;
				}
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
	        Total_time = TIME_ELAPSED;
        	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
        	Average_time = TIME_ELAPSED / ((double)num_messages);
	        fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	for (j=1;j<number_of_process;j++)
                pvm_kill(tid[j]);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	free(tid);
	free(effective_array_of_index);
	return 1;
	}

/* From here, is_empty == NOT_EMPTY */

if (send_mode == SEND)
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for (j=0;j<num_messages;j++)
		{
		for (i=1;i<number_of_process;i++)
			{
			if ((info = pvm_initsend(data_format))<0)
				{
				fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
				goto fail;
				}
			if ((info = pvm_pkint(outbuf,messages_length,1))<0)
				{
				fprintf(outfile,"\tpvm_pkint() : Failed with error %d\n",info);
				goto fail;
				}
			if ((info = pvm_send(tid[i],FUNNELING))<0)
				{
				fprintf(outfile,"\tpvm_send() : Failed with error %d\n",info);
				goto fail;
				}
			}
		for (i=1;i<number_of_process;i++)
			{
			for (count=0;count<BUSY_LOOP_PERF;count++)
                                if (pvm_probe(-1,FUNNELING)>0)
                                        break;
                        if (count== BUSY_LOOP_PERF)
                                {
                                fprintf(outfile,"\tTimeout expired \n");
                                goto fail;
                                }
			/*
			ack = timeout_wait_message(-1,FUNNELING,-1);
                                if (ack <0)
                                        goto fail;
			*/
			if ((info = pvm_recv(-1,FUNNELING))<0)
				{
				fprintf(outfile,"\tpvm_recv() : Failed with error %d\n",info);
				goto fail;
				}
			if ((info = pvm_upkint(inbuf,messages_length,1))<0)
				{
				fprintf(outfile,"\tpvm_upkint() : Failed with error %d\n",info);
				goto fail;
				}
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
        	Total_time = TIME_ELAPSED;
        	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
        	Average_time = TIME_ELAPSED / ((double)num_messages);
	        fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	for (j=1;j<number_of_process;j++)
                pvm_kill(tid[j]);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	free(tid);
	free(effective_array_of_index);
	return 1;
	}

if (send_mode == MCAST)
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for (j=0;j<num_messages;j++)
		{
		if ((info = pvm_initsend(data_format))<0)
			{	
			fprintf(outfile,"\tpvm_initsend() : Failed with error %d\n",info);
			goto fail;
			}
		if ((info = pvm_pkint(outbuf,messages_length,1))<0)
			{
			fprintf(outfile,"\tpvm_pkinf() : Failed with error %d\n",info);
			goto fail;
			}
		if ((info = pvm_mcast(tid+1,number_of_process-1,FUNNELING))<0)
			{
			fprintf(outfile,"\tpvm_mcast() : Failed with error %d\n",info);
			goto fail;
			}
		for (i=1;i<number_of_process;i++)
			{
			for (count=0;count<BUSY_LOOP_PERF;count++)
                                if (pvm_probe(-1,FUNNELING)>0)
                                        break;
                        if (count== BUSY_LOOP_PERF)
                                {
                                fprintf(outfile,"\tTimeout expired\n");
                                goto fail;
                                }
			/*
			ack = timeout_wait_message(-1,FUNNELING,-1);
                        if (ack <0)
                                goto fail;
			*/
			if ((info = pvm_recv(-1,FUNNELING))<0)
				{
				fprintf(outfile,"\tpvm_recv() : Failed with error %d\n",info);
				goto fail;
				}
			if ((info = pvm_upkint(inbuf,messages_length,1))<0)
				{
				fprintf(outfile,"\tpvm_upkint() : Failed with error %d\n",info);
				goto fail;
				}
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
        	Total_time = TIME_ELAPSED;
	        fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
        	Average_time = TIME_ELAPSED / ((double)num_messages);
	        fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	for (j=1;j<number_of_process;j++)
                pvm_kill(tid[j]);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	free(tid);
	free(effective_array_of_index);
	return 1;
	}

if (send_mode == PSEND)
	{
	if (timing_total||timing_average)
		gettimeofday(&t1,NULL);
	for (j=0;j<num_messages;j++)
		{
		for (i=1;i<number_of_process;i++)
			if ((info = pvm_psend(tid[i],FUNNELING,outbuf,messages_length,PVM_INT))<0)
				{
				fprintf(outfile,"\tpvm_psend() : Failed with error %d for host %s\n",
					info,hostpool[effective_array_of_index[i]]);
				goto fail;
				}
		for (i=1;i<number_of_process;i++)
			{
			for (count=0;count<BUSY_LOOP_PERF;count++)
                                if (pvm_probe(-1,FUNNELING)>0)
                                        break;
                        if (count== BUSY_LOOP_PERF)
                                {
                                fprintf(outfile,"\tTimeout expired\n");
                                goto fail;
                                }
			/*
			ack = timeout_wait_message(-1,FUNNELING,-1);
                        if (ack <0)
                                goto fail;
			*/
			if ((info = pvm_precv(-1,FUNNELING,inbuf,
				messages_length,PVM_INT,&atid,&atag,&alen))<0)
				{
				fprintf(outfile,"\tpvm_precv() : Failed with error %d\n",info);
				goto fail;
				}
			}
		}
	if (timing_total||timing_average)
		gettimeofday(&t2,NULL);
	if (timing_total)
		{
        	Total_time = TIME_ELAPSED;
        	fprintf(outfile,"\t Total time = %f sec.\n",Total_time);
		}
	if (timing_average)
		{
        	Average_time = TIME_ELAPSED / ((double)num_messages);
        	fprintf(outfile,"\t Average time = %f sec.\n",Average_time);
		}
	for (j=1;j<number_of_process;j++)
                pvm_kill(tid[j]);
	pvm_setopt(PvmRoute,PvmAllowDirect);
	free(tid);
	free(effective_array_of_index);
	return 1;
	}

fail :
for (i=1;i<number_of_process;i++)
	pvm_kill(tid[i]);
free(tid);
free(effective_array_of_index);
pvm_setopt(PvmRoute,PvmAllowDirect);
return -1;
}
	

	
/*      SLAVE   */
void funneling_slave(is_empty,send_mode,route,data_format)
int	is_empty;
int	send_mode;
int	route;
int	data_format;
{
int     *inbuf;
int     *outbuf;
int	atid,atag,alen;
int	length;

pvm_recv(pvm_parent(),ACKNOLEDGE);
pvm_upkint(&length,1,1);

inbuf = (int *)malloc(sizeof(int)*length);
outbuf = (int *)malloc(sizeof(int)*length);

pvm_initsend(PvmDataDefault);
pvm_send(pvm_parent(),ACKNOLEDGE);
pvm_setopt(PvmRoute,route);

if ((is_empty == EMPTY)&&((send_mode == SEND)||(send_mode == MCAST)))
        {
	while(1)
                {
                pvm_recv(pvm_parent(),FUNNELING);
                pvm_initsend(data_format);
                pvm_send(pvm_parent(),FUNNELING);
                }
        }
if ((is_empty == EMPTY)&&(send_mode == PSEND))
        {
        while(1)
                {
                pvm_precv(pvm_parent(),FUNNELING,inbuf,0,PVM_INT,&atid,&atag,&alen);
                pvm_psend(pvm_parent(),FUNNELING,outbuf,0,PVM_INT);
                }
        }
if ((send_mode == SEND)||(send_mode == MCAST))
        {
	while(1)
                {
                pvm_recv(pvm_parent(),FUNNELING);
		pvm_upkint(inbuf,length,1);
                pvm_initsend(data_format);
		pvm_pkint(outbuf,length,1);
                pvm_send(pvm_parent(),FUNNELING);
                }
        }

if (send_mode == PSEND)
        {
	while(1)
                {
                pvm_precv(pvm_parent(),FUNNELING,inbuf,length,PVM_INT,&atid,&atag,&alen);
                pvm_psend(pvm_parent(),FUNNELING,outbuf,length,PVM_INT);
                }
        }
pvm_exit();
}

