/******************************************************************************
 ***  MPI_Persistent_req_use_Event
 ******************************************************************************/
static int MPI_Persistent_req_use_Event (event_t * current,
	unsigned long long current_time, unsigned int cpu, unsigned int ptask,
	unsigned int task, unsigned int thread, FileSet_t *fset)
{
	thread_t * thread_info = GET_THREAD_INFO(ptask, task, thread);
	UINT64 valor;
	int tipus;
	double temps;

	UNREFERENCED_PARAMETER(cpu);

	temps = current_time-thread_info->Previous_Event_Time;
	temps /= 1000000000.0f;
	
	switch (Get_EvValue(current))
	{
		case EVT_BEGIN:
			Dimemas_CPU_Burst(fset->output_file, task-1, thread-1, temps);
		break;

		case EVT_END:
#ifdef CPUZERO
			Dimemas_CPU_Burst(fset->output_file, task-1, thread-1, 0);
#endif
		break;
	}

	Translate_MPI_MPIT2PRV (Get_EvEvent(current), Get_EvValue(current), &tipus, &valor);
	Dimemas_User_Event (fset->output_file, task-1, thread-1, tipus, valor);

	return 0;
}
static int ANY_Send_Event (event_t * current, unsigned long long current_time,
	unsigned int cpu, unsigned int ptask, unsigned int task,
	unsigned int thread, FileSet_t *fset)
{
	thread_t * thread_info = GET_THREAD_INFO(ptask, task, thread);
	int tipus;
	int isimmediate;
	int comunicador;
	UINT64 valor;
	double temps;

	UNREFERENCED_PARAMETER(cpu);

	if (MPI_IBSEND_EV == Get_EvEvent(current) 
	    || MPI_ISSEND_EV == Get_EvEvent(current)
	    || MPI_IRSEND_EV == Get_EvEvent(current)
	    || MPI_ISEND_EV == Get_EvEvent(current))
	   	isimmediate = TRUE;
	else
		isimmediate = FALSE;

	temps = current_time-thread_info->Previous_Event_Time;
	temps /= 1000000000.0f;

	comunicador = alies_comunicador (Get_EvComm(current), 1, task);
	
	switch (Get_EvValue(current)) {
		case EVT_BEGIN:
			Dimemas_CPU_Burst (fset->output_file, task-1, thread-1, temps);
		break;

		case EVT_END: 
			if (Get_EvTarget(current) != MPI_PROC_NULL)
			{
#ifdef CPUZERO
				Dimemas_CPU_Burst (fset->output_file, task-1, thread-1, 0);
#endif
				if (!isimmediate)
					Dimemas_NX_BlockingSend (fset->output_file, task-1, thread-1, Get_EvTarget(current),
					  comunicador, Get_EvSize(current), Get_EvTag(current));
				else
					Dimemas_NX_ImmediateSend (fset->output_file, task-1, thread-1, Get_EvTarget(current),
					  comunicador, Get_EvSize(current), Get_EvTag(current));
			}
#ifdef CPUZERO
			Dimemas_CPU_Burst (fset->output_file, task-1, thread-1, 0);
#endif
		break;
	}

	Translate_MPI_MPIT2PRV (Get_EvEvent(current), Get_EvValue(current), &tipus, &valor);
	Dimemas_User_Event (fset->output_file, task-1, thread-1, tipus, valor);
	return 0;
}
/******************************************************************************
 ***  trace_paraver_event
 ******************************************************************************/
void trace_paraver_event (
   unsigned int cpu, unsigned int ptask, unsigned int task, unsigned int thread,
   unsigned long long time, 
   unsigned int type, UINT64 value)
{
	thread_t * thread_info;
	paraver_rec_t record;
	int tipus;
	UINT64 valor;
	thread_info = GET_THREAD_INFO (ptask, task, thread);
	WriteFileBuffer_t *wfb = thread_info->file->wfb;

#if !defined(DCARRERA_HADOOP)
	if (!EnabledTasks[ptask - 1][task - 1])
		return;
#endif

	if (type >= MPI_MIN_EV && type <= MPI_MAX_EV)
	{
		Translate_MPI_MPIT2PRV (type, value, &tipus, &valor);
	}
	else
	{
		tipus = type;
		valor = value;
	}
	
	record.type = EVENT;
	record.cpu = cpu;
	record.ptask = ptask;
	record.task = task;
	record.thread = thread_info->virtual_thread;
	record.time = time;
	record.event = tipus;
	record.value = valor;

	trace_paraver_record (wfb, &record);
}
static int GlobalOP_Event (event_t * current, unsigned long long current_time,
	unsigned int cpu, unsigned int ptask, unsigned int task, unsigned int thread,
	FileSet_t *fset)
{
	thread_t * thread_info = GET_THREAD_INFO(ptask, task, thread);
	UINT64 valor;
	int tipus;
	double temps;

	UNREFERENCED_PARAMETER(cpu);

	temps = current_time-thread_info->Previous_Event_Time;
	temps /= 1000000000.0f;

	if (EVT_BEGIN == Get_EvValue(current))
	{
		UINT64 bsent = Get_GlobalOP_SendSize(current);
		UINT64 brecv = Get_GlobalOP_RecvSize(current);
		int root_rank = Get_GlobalOP_RootRank(current);
		int thd_rank = Get_GlobalOP_RootThd(current);
		int commid = Get_GlobalOP_CommID(current, task);
		int ID = Get_GlobalOP_ID(Get_EvEvent(current));

		Dimemas_CPU_Burst (fset->output_file, task-1, thread-1, temps);
		Dimemas_Global_OP (fset->output_file, task-1, thread-1, ID, commid, root_rank, thd_rank, bsent, brecv );
	}
	else if (EVT_END == Get_EvValue(current))
	{
#ifdef CPUZERO
		Dimemas_CPU_Burst (fset->output_file, task-1, thread-1, 0);
#endif
	}

	Translate_MPI_MPIT2PRV (Get_EvEvent(current), Get_EvValue(current), &tipus, &valor);
	Dimemas_User_Event (fset->output_file, task-1, thread-1, tipus, valor);
	return 0;
}
/******************************************************************************
 ***  Sendrecv_Event
 ******************************************************************************/
static int SendRecv_Event (event_t * current, unsigned long long current_time,
	unsigned int cpu, unsigned int ptask, unsigned int task, unsigned int thread,
	FileSet_t *fset)
{
	static unsigned int receiver, send_tag;
	static int send_size;
	thread_t * thread_info = GET_THREAD_INFO(ptask, task, thread);
	UINT64 valor;
	unsigned int sender = 0;
	unsigned int receive_tag = 0;
	unsigned int receive_size = 0;
	int tipus;
	int comunicador;
	double temps;

	UNREFERENCED_PARAMETER(cpu);

	temps = current_time-thread_info->Previous_Event_Time;
	temps /= 1000000000.0f;

	comunicador = alies_comunicador (Get_EvComm(current), 1, task);
	
	switch( Get_EvValue(current) )
	{
		case EVT_BEGIN:
			Dimemas_CPU_Burst(fset->output_file, task-1, thread-1, temps);
			receiver= Get_EvTarget(current);
			send_tag= Get_EvTag(current);
			send_size= Get_EvSize(current);
		break;

		case EVT_END:
#ifdef CPUZERO
			MPTRACE_ERROR(Dimemas_CPU_Burst(fset->output_file, task-1, thread-1, 0));
#endif
			if (Get_EvTarget( current ) != MPI_PROC_NULL)
			{
				sender= Get_EvTarget(current);
				receive_tag= Get_EvTag(current);
				receive_size= Get_EvSize(current);                       

#ifdef CPUZERO
				Dimemas_CPU_Burst(fset->output_file, task-1, thread-1, 0);
#endif
				Dimemas_NX_Irecv (fset->output_file, task-1, thread-1, sender, comunicador, receive_size, receive_tag);
			}

			if (receiver != MPI_PROC_NULL)
			{
#ifdef CPUZERO
				Dimemas_CPU_Burst(fset->output_file, task-1, thread-1, 0);
#endif
				Dimemas_NX_BlockingSend (fset->output_file, task-1, thread-1, receiver, Get_EvComm(current), send_size, send_tag);
			}

			if (Get_EvTarget( current ) != MPI_PROC_NULL)
			{
#ifdef CPUZERO
				Dimemas_CPU_Burst(fset->output_file, task-1, thread-1, 0);
#endif
				Dimemas_NX_Wait (fset->output_file, task-1, thread-1, sender, comunicador, receive_size, receive_tag);
			}
#ifdef CPUZERO
			Dimemas_CPU_Burst(fset->output_file, task-1, thread-1, 0);
#endif
		break;
	}

	Translate_MPI_MPIT2PRV (Get_EvEvent(current), Get_EvValue(current), &tipus, &valor);
	Dimemas_User_Event (fset->output_file, task-1, thread-1, tipus, valor);

	return 0;
}