/*
 *             	    Exemple "Master12.c" PVM versio 3.3
 *	    	Susana Maria Bajo Sanchez (ei05646@salleURL.edu)
 *	    	Josep Maria Garrell i Guiu (josepmg@salleURL.edu)
 *		 	      Software Paral.lel
 *		         Departament d'Informatica (DI)
 *	               Enginyeria i Arquitectura La Salle
 *		         Universitat Ramon Llull (URL)
 * 			        Curs 1999/2000
*/

#include <stdio.h>
#include <sys/time.h>
#include "pvm3.h"

int mytid;
int tids[32];
int n, nproc, i, who, msgtype, cc;
float data[100], result[32];

int info;
struct timeval tmout;

//---------------------------------------------------------------------------
void initialize_data (float data[100],int n)
{
	for (i=0;i<100;i++) data[i]=n;
}

//---------------------------------------------------------------------------
void main()
{
	// salida estandar por pantalla
	pvm_catchout(stdout);

	mytid = pvm_mytid();
	printf("Master12: Soy la tarea #%x\n",mytid);

	// inicio de todas las tareas "slaves"
	puts("¿Cuantos programas 'SLAVES' quieres (1-32)?");
	scanf("%d",&nproc);
	
	cc = pvm_spawn("Slave1",(char**)0,0,"",nproc,tids);
	if (cc==nproc)
		{
		printf("Master12: He podido crear las %d tareas 'Slave1'\n",nproc);

		// inicio del programa
		n = 1;
		initialize_data(data,n);
		
		// broadcast del dato inicial a las tareas "slaves"
		pvm_initsend(PvmDataRaw);
		pvm_pkint(&nproc,1,1);
		pvm_pkint(tids,nproc,1);
		pvm_pkint(&n,1,1);
		pvm_pkfloat(data,n,1);
		pvm_mcast(tids,nproc,0);

		// esperar los resultados de los "slaves"
		msgtype = 5;
		for (i=0;i<nproc;i++)
			{
			// recibir con "timeout"
			tmout.tv_sec = 60;
			tmout.tv_usec = 0;
			if ((info = pvm_trecv(-1,msgtype,&tmout))>0)
				{
				pvm_upkint(&who,1,1);
				pvm_upkfloat(&result[who],1,1);
				printf("Yo tengo %x de %d\n", result[who],who);
				}
				// si hay problemas en al recepcion mata las tareas
				else 
                                     {
			             printf("Master12: Se ha superado el timeout\n"); 	
                                     pvm_kill(tids[i]);
				     }
			}
		}
		else 
			{
			// mata las tareas hijas que si se han podido crear
			for (i=0;i<cc;i++) pvm_kill(tids[i]);
			printf("Master12: No he podido crear las tareas 'Slaves1'\n");
			}

	printf("Master12: Salgo de PVM\n");
	pvm_exit();
}

