Blame src/mpi/datatype/get_address.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *
Packit Service c5cf8c
 *  (C) 2001 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#include "mpiimpl.h"
Packit Service c5cf8c
Packit Service c5cf8c
/* -- Begin Profiling Symbol Block for routine MPI_Get_address */
Packit Service c5cf8c
#if defined(HAVE_PRAGMA_WEAK)
Packit Service c5cf8c
#pragma weak MPI_Get_address = PMPI_Get_address
Packit Service c5cf8c
#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
Packit Service c5cf8c
#pragma _HP_SECONDARY_DEF PMPI_Get_address  MPI_Get_address
Packit Service c5cf8c
#elif defined(HAVE_PRAGMA_CRI_DUP)
Packit Service c5cf8c
#pragma _CRI duplicate MPI_Get_address as PMPI_Get_address
Packit Service c5cf8c
#elif defined(HAVE_WEAK_ATTRIBUTE)
Packit Service c5cf8c
int MPI_Get_address(const void *location, MPI_Aint * address)
Packit Service c5cf8c
    __attribute__ ((weak, alias("PMPI_Get_address")));
Packit Service c5cf8c
#endif
Packit Service c5cf8c
/* -- End Profiling Symbol Block */
Packit Service c5cf8c
Packit Service c5cf8c
/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
Packit Service c5cf8c
   the MPI routines */
Packit Service c5cf8c
#ifndef MPICH_MPI_FROM_PMPI
Packit Service c5cf8c
#undef MPI_Get_address
Packit Service c5cf8c
#define MPI_Get_address PMPI_Get_address
Packit Service c5cf8c
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPI_Get_address
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME "MPI_Get_address"
Packit Service c5cf8c
Packit Service c5cf8c
/*@
Packit Service c5cf8c
   MPI_Get_address - Get the address of a location in memory
Packit Service c5cf8c
Packit Service c5cf8c
Input Parameters:
Packit Service c5cf8c
. location - location in caller memory (choice)
Packit Service c5cf8c
Packit Service c5cf8c
Output Parameters:
Packit Service c5cf8c
. address - address of location (address integer)
Packit Service c5cf8c
Packit Service c5cf8c
   Notes:
Packit Service c5cf8c
    This routine is provided for both the Fortran and C programmers.
Packit Service c5cf8c
    On many systems, the address returned by this routine will be the same
Packit Service c5cf8c
    as produced by the C '&' operator, but this is not required in C and
Packit Service c5cf8c
    may not be true of systems with word- rather than byte-oriented
Packit Service c5cf8c
    instructions or systems with segmented address spaces.
Packit Service c5cf8c
Packit Service c5cf8c
    This routine should be used instead of 'MPI_Address'.
Packit Service c5cf8c
Packit Service c5cf8c
.N SignalSafe
Packit Service c5cf8c
Packit Service c5cf8c
.N Fortran
Packit Service c5cf8c
Packit Service c5cf8c
 In Fortran, the integer type is always signed.  This can cause problems
Packit Service c5cf8c
 on systems where the address fits into a four byte unsigned integer but
Packit Service c5cf8c
 the value is larger than the largest signed integer.  For example, a system
Packit Service c5cf8c
 with more than 2 GBytes of memory may have addresses that do not fit within
Packit Service c5cf8c
 a four byte signed integer.  Unfortunately, there is no easy solution to
Packit Service c5cf8c
 this problem, as there is no Fortran datatype that can be used here (using
Packit Service c5cf8c
 a longer integer type will cause other problems, as well as surprising
Packit Service c5cf8c
 users when the size of the integer type is larger that the size of a pointer
Packit Service c5cf8c
 in C).  In this case, it is recommended that you use C to manipulate
Packit Service c5cf8c
 addresses.
Packit Service c5cf8c
Packit Service c5cf8c
.N Errors
Packit Service c5cf8c
.N MPI_SUCCESS
Packit Service c5cf8c
.N MPI_ERR_OTHER
Packit Service c5cf8c
@*/
Packit Service c5cf8c
int MPI_Get_address(const void *location, MPI_Aint * address)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPI_GET_ADDRESS);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_ERRTEST_INITIALIZED_ORDIE();
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPI_GET_ADDRESS);
Packit Service c5cf8c
Packit Service c5cf8c
    /* Validate parameters and objects (post conversion) */
Packit Service c5cf8c
#ifdef HAVE_ERROR_CHECKING
Packit Service c5cf8c
    {
Packit Service c5cf8c
        MPID_BEGIN_ERROR_CHECKS;
Packit Service c5cf8c
        {
Packit Service c5cf8c
            MPIR_ERRTEST_ARGNULL(address, "address", mpi_errno);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        MPID_END_ERROR_CHECKS;
Packit Service c5cf8c
    }
Packit Service c5cf8c
#endif /* HAVE_ERROR_CHECKING */
Packit Service c5cf8c
Packit Service c5cf8c
    /* ... body of routine ...  */
Packit Service c5cf8c
Packit Service c5cf8c
    /* SX_4 needs to set CHAR_PTR_IS_ADDRESS
Packit Service c5cf8c
     * The reason is that it computes the different in two pointers in
Packit Service c5cf8c
     * an "int", and addresses typically have the high (bit 31) bit set;
Packit Service c5cf8c
     * thus the difference, when cast as MPI_Aint (long), is sign-extended,
Packit Service c5cf8c
     * making the absolute address negative.  Without a copy of the C
Packit Service c5cf8c
     * standard, I can't tell if this is a compiler bug or a language bug.
Packit Service c5cf8c
     */
Packit Service c5cf8c
#ifdef CHAR_PTR_IS_ADDRESS
Packit Service c5cf8c
    *address = MPIR_VOID_PTR_CAST_TO_MPI_AINT((char *) location);
Packit Service c5cf8c
#else
Packit Service c5cf8c
    /* Note that this is the "portable" way to generate an address.
Packit Service c5cf8c
     * The difference of two pointers is the number of elements
Packit Service c5cf8c
     * between them, so this gives the number of chars between location
Packit Service c5cf8c
     * and ptr.  As long as sizeof(char) represents one byte,
Packit Service c5cf8c
     * of bytes from 0 to location */
Packit Service c5cf8c
    *address = MPIR_VOID_PTR_CAST_TO_MPI_AINT((char *) location - (char *) MPI_BOTTOM);
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    /* The same code is used in MPI_Address */
Packit Service c5cf8c
Packit Service c5cf8c
    /* ... end of body of routine ... */
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef HAVE_ERROR_CHECKING
Packit Service c5cf8c
  fn_exit:
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_GET_ADDRESS);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
Packit Service c5cf8c
    /* --BEGIN ERROR HANDLING-- */
Packit Service c5cf8c
#ifdef HAVE_ERROR_CHECKING
Packit Service c5cf8c
  fn_fail:
Packit Service c5cf8c
    {
Packit Service c5cf8c
        mpi_errno =
Packit Service c5cf8c
            MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
Packit Service c5cf8c
                                 "**mpi_get_address", "**mpi_get_address %p %p", location, address);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    mpi_errno = MPIR_Err_return_comm(0, FCNAME, mpi_errno);
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    /* --END ERROR HANDLING-- */
Packit Service c5cf8c
}