/* -*- c-file-style: "GNU" -*- */
/*
 * Copyright (C) CNRS, INRIA, Universite Bordeaux 1, Telecom SudParis
 * See COPYING in top-level directory.
 */

#ifndef _REENTRANT
#define _REENTRANT
#endif

#include "mpi_eztrace.h"

#include <dlfcn.h>
#include <eztrace-lib/eztrace.h>
#include <mpi.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <unistd.h>
#include <eztrace-core/eztrace_attributes.h>

void _ezt_MPI_Start_request(MPI_Request* req) {
  if(!EZTRACE_SAFE)
    return;
  if(*req == MPI_REQUEST_NULL)
    return;

  struct ezt_mpi_request* r = ezt_mpi_get_request_type((MPI_Request*)req, 1);
  if(!r)
    return;

  if(r->type == recv) {
    OTF2_ErrorCode err = OTF2_EvtWriter_MpiIrecvRequest(evt_writer,
							NULL,
							ezt_get_timestamp(),
							(uint64_t)r->req);
    if(err != OTF2_SUCCESS) {
      eztrace_warn("OTF2 error: %s: %s\n", OTF2_Error_GetName(err),
		   OTF2_Error_GetDescription(err));
    }
  } else if(r->type == send  ||
	    r->type == bsend ||
	    r->type == rsend ||
	    r->type == ssend ) {
    OTF2_ErrorCode err = OTF2_EvtWriter_MpiIsend(evt_writer,
						 NULL,
						 ezt_get_timestamp(),
						 r->dest,
						 MPI_TO_OTF_COMMUNICATOR(r->comm),
						 r->tag,
						 r->len,
						 (uint64_t)r->req);
    if(err != OTF2_SUCCESS) {
      eztrace_warn("OTF2 error: %s: %s\n", OTF2_Error_GetName(err), OTF2_Error_GetDescription(err));
    }
  }
}

static void MPI_Start_prolog(MPI_Fint* req) {
  _ezt_MPI_Start_request((MPI_Request*)req);
}

static int MPI_Start_core(MPI_Request* req) {
  return libMPI_Start(req);
}

int MPI_Start(MPI_Request* req) {
  FUNCTION_ENTRY;

  MPI_Start_prolog((MPI_Fint*)req);
  int ret = MPI_Start_core(req);

  FUNCTION_EXIT;
  return ret;
}

void mpif_start_(MPI_Fint* req,
		 int* error) {
  FUNCTION_ENTRY_("mpi_start_");
  MPI_Request c_req = MPI_Request_f2c(*req);

  MPI_Start_prolog(req);
  *error = MPI_Start_core(&c_req);

  *req = MPI_Request_c2f(c_req);
  FUNCTION_EXIT_("mpi_start_");
}
