Blame src/mpi/attr/win_get_attr.c

Packit 0848f5
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit 0848f5
/*
Packit 0848f5
 *
Packit 0848f5
 *  (C) 2001 by Argonne National Laboratory.
Packit 0848f5
 *      See COPYRIGHT in top-level directory.
Packit 0848f5
 */
Packit 0848f5
Packit 0848f5
#include "mpiimpl.h"
Packit 0848f5
Packit 0848f5
/* -- Begin Profiling Symbol Block for routine MPI_Win_get_attr */
Packit 0848f5
#if defined(HAVE_PRAGMA_WEAK)
Packit 0848f5
#pragma weak MPI_Win_get_attr = PMPI_Win_get_attr
Packit 0848f5
#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
Packit 0848f5
#pragma _HP_SECONDARY_DEF PMPI_Win_get_attr  MPI_Win_get_attr
Packit 0848f5
#elif defined(HAVE_PRAGMA_CRI_DUP)
Packit 0848f5
#pragma _CRI duplicate MPI_Win_get_attr as PMPI_Win_get_attr
Packit 0848f5
#elif defined(HAVE_WEAK_ATTRIBUTE)
Packit 0848f5
int MPI_Win_get_attr(MPI_Win win, int win_keyval, void *attribute_val, int *flag) __attribute__((weak,alias("PMPI_Win_get_attr")));
Packit 0848f5
#endif
Packit 0848f5
/* -- End Profiling Symbol Block */
Packit 0848f5
Packit 0848f5
/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
Packit 0848f5
   the MPI routines */
Packit 0848f5
#ifndef MPICH_MPI_FROM_PMPI
Packit 0848f5
#undef MPI_Win_get_attr
Packit 0848f5
#define MPI_Win_get_attr PMPI_Win_get_attr
Packit 0848f5
Packit 0848f5
#undef FUNCNAME
Packit 0848f5
#define FUNCNAME MPIR_WinGetAttr
Packit 0848f5
#undef FCNAME
Packit 0848f5
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit 0848f5
int MPIR_WinGetAttr( MPI_Win win, int win_keyval, void *attribute_val, 
Packit 0848f5
		     int *flag, MPIR_AttrType outAttrType )
Packit 0848f5
{
Packit 0848f5
    int mpi_errno = MPI_SUCCESS;
Packit 0848f5
    MPID_Win *win_ptr = NULL;
Packit 0848f5
    MPID_MPI_STATE_DECL(MPID_STATE_MPIR_WIN_GET_ATTR);
Packit 0848f5
Packit 0848f5
    MPIR_ERRTEST_INITIALIZED_ORDIE();
Packit 0848f5
    
Packit 0848f5
    MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
Packit 0848f5
    MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_WIN_GET_ATTR);
Packit 0848f5
Packit 0848f5
    /* Validate parameters, especially handles needing to be converted */
Packit 0848f5
#   ifdef HAVE_ERROR_CHECKING
Packit 0848f5
    {
Packit 0848f5
        MPID_BEGIN_ERROR_CHECKS;
Packit 0848f5
        {
Packit 0848f5
	    MPIR_ERRTEST_WIN(win, mpi_errno);
Packit 0848f5
	    MPIR_ERRTEST_KEYVAL(win_keyval, MPID_WIN, "window", mpi_errno);
Packit 0848f5
#           ifdef NEEDS_POINTER_ALIGNMENT_ADJUST
Packit 0848f5
            /* A common user error is to pass the address of a 4-byte
Packit 0848f5
	       int when the address of a pointer (or an address-sized int)
Packit 0848f5
	       should have been used.  We can test for this specific
Packit 0848f5
	       case.  Note that this code assumes sizeof(MPIU_Pint) is
Packit 0848f5
	       a power of 2. */
Packit 0848f5
	    if ((MPIU_Pint)attribute_val & (sizeof(MPIU_Pint)-1)) {
Packit 0848f5
		MPIR_ERR_SETANDSTMT(mpi_errno,MPI_ERR_ARG,goto fn_fail,"**attrnotptr");
Packit 0848f5
	    }
Packit 0848f5
#           endif
Packit 0848f5
        }
Packit 0848f5
        MPID_END_ERROR_CHECKS;
Packit 0848f5
    }
Packit 0848f5
#   endif
Packit 0848f5
    
Packit 0848f5
    /* Convert MPI object handles to object pointers */
Packit 0848f5
    MPID_Win_get_ptr( win, win_ptr );
Packit 0848f5
    
Packit 0848f5
    /* Validate parameters and objects (post conversion) */
Packit 0848f5
#   ifdef HAVE_ERROR_CHECKING
Packit 0848f5
    {
Packit 0848f5
	MPID_BEGIN_ERROR_CHECKS;
Packit 0848f5
	{
Packit 0848f5
            /* Validate win_ptr */
Packit 0848f5
            MPID_Win_valid_ptr( win_ptr, mpi_errno );
Packit 0848f5
	    /* If win_ptr is not valid, it will be reset to null */
Packit 0848f5
	    MPIR_ERRTEST_ARGNULL(attribute_val, "attribute_val", mpi_errno);
Packit 0848f5
	    MPIR_ERRTEST_ARGNULL(flag, "flag", mpi_errno);
Packit 0848f5
	}
Packit 0848f5
	MPID_END_ERROR_CHECKS;
Packit 0848f5
    }
Packit 0848f5
#   endif /* HAVE_ERROR_CHECKING */    
Packit 0848f5
Packit 0848f5
    /* ... body of routine ...  */
Packit 0848f5
    
Packit 0848f5
    /* Check for builtin attribute */
Packit 0848f5
    /* This code is ok for correct programs, but it would be better
Packit 0848f5
       to copy the values from the per-process block and pass the user
Packit 0848f5
       a pointer to a copy */
Packit 0848f5
    /* Note that if we are called from Fortran, we must return the values,
Packit 0848f5
       not the addresses, of these attributes */
Packit 0848f5
    if (HANDLE_GET_KIND(win_keyval) == HANDLE_KIND_BUILTIN) {
Packit 0848f5
	void **attr_val_p = (void **)attribute_val;
Packit 0848f5
#ifdef HAVE_FORTRAN_BINDING
Packit 0848f5
	/* Note that this routine only has a Fortran 90 binding,
Packit 0848f5
	   so the attribute value is an address-sized int */
Packit 0848f5
	MPIU_Pint  *attr_int = (MPIU_Pint *)attribute_val;
Packit 0848f5
#endif
Packit 0848f5
	*flag = 1;
Packit 0848f5
Packit 0848f5
	/* 
Packit 0848f5
	 * The C versions of the attributes return the address of a 
Packit 0848f5
	 * *COPY* of the value (to prevent the user from changing it)
Packit 0848f5
	 * and the Fortran versions provide the actual value (as a Fint)
Packit 0848f5
	 */
Packit 0848f5
	switch (win_keyval) {
Packit 0848f5
	case MPI_WIN_BASE:
Packit 0848f5
	    *attr_val_p = win_ptr->base;
Packit 0848f5
	    break;
Packit 0848f5
	case MPI_WIN_SIZE:
Packit 0848f5
	    win_ptr->copySize = win_ptr->size;
Packit 0848f5
	    *attr_val_p = &win_ptr->copySize;
Packit 0848f5
	    break;
Packit 0848f5
	case MPI_WIN_DISP_UNIT:
Packit 0848f5
	    win_ptr->copyDispUnit = win_ptr->disp_unit;
Packit 0848f5
	    *attr_val_p = &win_ptr->copyDispUnit;
Packit 0848f5
	    break;
Packit 0848f5
	case MPI_WIN_CREATE_FLAVOR:
Packit 0848f5
	    win_ptr->copyCreateFlavor = win_ptr->create_flavor;
Packit 0848f5
	    *attr_val_p = &win_ptr->copyCreateFlavor;
Packit 0848f5
	    break;
Packit 0848f5
	case MPI_WIN_MODEL:
Packit 0848f5
	    win_ptr->copyModel = win_ptr->model;
Packit 0848f5
	    *attr_val_p = &win_ptr->copyModel;
Packit 0848f5
	    break;
Packit 0848f5
#ifdef HAVE_FORTRAN_BINDING
Packit 0848f5
	case MPIR_ATTR_C_TO_FORTRAN(MPI_WIN_BASE):
Packit 0848f5
	    /* The Fortran routine that matches this routine should
Packit 0848f5
	       provide an address-sized integer, not an MPI_Fint */
Packit 0848f5
	    *attr_int = MPIU_VOID_PTR_CAST_TO_MPI_AINT(win_ptr->base);
Packit 0848f5
	    break;
Packit 0848f5
        case MPIR_ATTR_C_TO_FORTRAN(MPI_WIN_SIZE):
Packit 0848f5
	    /* We do not need to copy because we return the value,
Packit 0848f5
	       not a pointer to the value */
Packit 0848f5
	    *attr_int = win_ptr->size;
Packit 0848f5
	    break;
Packit 0848f5
	case MPIR_ATTR_C_TO_FORTRAN(MPI_WIN_DISP_UNIT):
Packit 0848f5
	    /* We do not need to copy because we return the value,
Packit 0848f5
	       not a pointer to the value */
Packit 0848f5
	    *attr_int = win_ptr->disp_unit;
Packit 0848f5
	    break;
Packit 0848f5
	case MPIR_ATTR_C_TO_FORTRAN(MPI_WIN_CREATE_FLAVOR):
Packit 0848f5
	    *attr_int = win_ptr->create_flavor;
Packit 0848f5
	    break;
Packit 0848f5
	case MPIR_ATTR_C_TO_FORTRAN(MPI_WIN_MODEL):
Packit 0848f5
	    *attr_int = win_ptr->model;
Packit 0848f5
	    break;
Packit 0848f5
#endif
Packit 0848f5
        default:
Packit 0848f5
            MPIU_Assert(FALSE);
Packit 0848f5
            break;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	MPID_Attribute *p = win_ptr->attributes;
Packit 0848f5
Packit 0848f5
	*flag = 0;
Packit 0848f5
	while (p) {
Packit 0848f5
	    if (p->keyval->handle == win_keyval) {
Packit 0848f5
		*flag = 1;
Packit 0848f5
		if (outAttrType == MPIR_ATTR_PTR) {
Packit 0848f5
		    if (p->attrType == MPIR_ATTR_INT) {
Packit 0848f5
			/* This is the tricky case: if the system is
Packit 0848f5
			   bigendian, and we have to return a pointer to
Packit 0848f5
			   an int, then we may need to point to the 
Packit 0848f5
			   correct location in the word. */
Packit 0848f5
#if defined(WORDS_LITTLEENDIAN) || (SIZEOF_VOID_P == SIZEOF_INT)
Packit 0848f5
			*(void**)attribute_val = &(p->value);
Packit 0848f5
#else
Packit 0848f5
			int *p_loc = (int *)&(p->value);
Packit 0848f5
#if SIZEOF_VOID_P == 2 * SIZEOF_INT
Packit 0848f5
			p_loc++;
Packit 0848f5
#else 
Packit 0848f5
#error Expected sizeof(void*) to be either sizeof(int) or 2*sizeof(int)
Packit 0848f5
#endif
Packit 0848f5
			*(void **)attribute_val = p_loc;
Packit 0848f5
#endif
Packit 0848f5
		    }
Packit 0848f5
		    else if (p->attrType == MPIR_ATTR_AINT) {
Packit 0848f5
			*(void**)attribute_val = &(p->value);
Packit 0848f5
		    }
Packit 0848f5
		    else {
Packit 0848f5
			*(void**)attribute_val = (void *)(MPIU_Pint)(p->value);
Packit 0848f5
		    }
Packit 0848f5
		}
Packit 0848f5
		else
Packit 0848f5
		    *(void**)attribute_val = (void *)(MPIU_Pint)(p->value);
Packit 0848f5
		
Packit 0848f5
		break;
Packit 0848f5
	    }
Packit 0848f5
	    p = p->next;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    /* ... end of body of routine ... */
Packit 0848f5
Packit 0848f5
#ifdef HAVE_ERROR_CHECKING
Packit 0848f5
  fn_exit:
Packit 0848f5
#endif
Packit 0848f5
    MPID_MPI_FUNC_EXIT(MPID_STATE_MPIR_WIN_GET_ATTR);
Packit 0848f5
    MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
Packit 0848f5
    return mpi_errno;
Packit 0848f5
Packit 0848f5
    /* --BEGIN ERROR HANDLING-- */
Packit 0848f5
#   ifdef HAVE_ERROR_CHECKING
Packit 0848f5
  fn_fail:
Packit 0848f5
    {
Packit 0848f5
	mpi_errno = MPIR_Err_create_code(
Packit 0848f5
	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, 
Packit 0848f5
	    "**mpir_wingetattr", 
Packit 0848f5
	    "**mpir_wingetattr %W %d %p %p", 
Packit 0848f5
	    win, win_keyval, attribute_val, flag);
Packit 0848f5
    }
Packit 0848f5
    mpi_errno = MPIR_Err_return_win( win_ptr, FCNAME, mpi_errno );
Packit 0848f5
    goto fn_exit;
Packit 0848f5
#   endif
Packit 0848f5
    /* --END ERROR HANDLING-- */
Packit 0848f5
}
Packit 0848f5
#endif
Packit 0848f5
Packit 0848f5
#undef FUNCNAME
Packit 0848f5
#define FUNCNAME MPI_Win_get_attr
Packit 0848f5
#undef FCNAME
Packit 0848f5
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit 0848f5
/*@
Packit 0848f5
   MPI_Win_get_attr - Get attribute cached on an MPI window object
Packit 0848f5
Packit 0848f5
Input Parameters:
Packit 0848f5
+ win - window to which the attribute is attached (handle) 
Packit 0848f5
- win_keyval - key value (integer) 
Packit 0848f5
Packit 0848f5
Output Parameters:
Packit 0848f5
+ attribute_val - attribute value, unless flag is false 
Packit 0848f5
- flag - false if no attribute is associated with the key (logical) 
Packit 0848f5
Packit 0848f5
   Notes:
Packit 0848f5
   The following attributes are predefined for all MPI Window objects\:
Packit 0848f5
Packit 0848f5
+ MPI_WIN_BASE - window base address. 
Packit 0848f5
. MPI_WIN_SIZE - window size, in bytes. 
Packit 0848f5
- MPI_WIN_DISP_UNIT - displacement unit associated with the window. 
Packit 0848f5
Packit 0848f5
.N ThreadSafe
Packit 0848f5
Packit 0848f5
.N Fortran
Packit 0848f5
Packit 0848f5
.N Errors
Packit 0848f5
.N MPI_SUCCESS
Packit 0848f5
.N MPI_ERR_WIN
Packit 0848f5
.N MPI_ERR_KEYVAL
Packit 0848f5
.N MPI_ERR_OTHER
Packit 0848f5
@*/
Packit 0848f5
int MPI_Win_get_attr(MPI_Win win, int win_keyval, void *attribute_val, 
Packit 0848f5
		     int *flag)
Packit 0848f5
{
Packit 0848f5
    int mpi_errno = MPI_SUCCESS;
Packit 0848f5
#ifdef HAVE_ERROR_CHECKING
Packit 0848f5
    MPID_Win *win_ptr = NULL;
Packit 0848f5
#endif
Packit 0848f5
    MPID_MPI_STATE_DECL(MPID_STATE_MPI_WIN_GET_ATTR);
Packit 0848f5
Packit 0848f5
    MPIR_ERRTEST_INITIALIZED_ORDIE();
Packit 0848f5
    
Packit 0848f5
    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_WIN_GET_ATTR);
Packit 0848f5
Packit 0848f5
    /* ... body of routine ...  */
Packit 0848f5
    mpi_errno = MPIR_WinGetAttr( win, win_keyval, attribute_val, flag, 
Packit 0848f5
				 MPIR_ATTR_PTR );
Packit 0848f5
    if (mpi_errno) goto fn_fail;
Packit 0848f5
    /* ... end of body of routine ... */
Packit 0848f5
Packit 0848f5
  fn_exit:
Packit 0848f5
    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_WIN_GET_ATTR);
Packit 0848f5
    return mpi_errno;
Packit 0848f5
Packit 0848f5
    /* --BEGIN ERROR HANDLING-- */
Packit 0848f5
  fn_fail:
Packit 0848f5
#ifdef HAVE_ERROR_CHECKING
Packit 0848f5
    {
Packit 0848f5
	mpi_errno = MPIR_Err_create_code(
Packit 0848f5
	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, 
Packit 0848f5
	    "**mpi_win_get_attr", 
Packit 0848f5
	    "**mpi_win_get_attr %W %d %p %p", 
Packit 0848f5
	    win, win_keyval, attribute_val, flag);
Packit 0848f5
    }
Packit 0848f5
    MPID_Win_get_ptr( win, win_ptr );
Packit 0848f5
    mpi_errno = MPIR_Err_return_win( win_ptr, FCNAME, mpi_errno );
Packit 0848f5
#endif
Packit 0848f5
    goto fn_exit;
Packit 0848f5
    /* --END ERROR HANDLING-- */
Packit 0848f5
}