Blame src/mpi/attr/win_set_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
#include "attr.h"
Packit 0848f5
Packit 0848f5
/* -- Begin Profiling Symbol Block for routine MPI_Win_set_attr */
Packit 0848f5
#if defined(HAVE_PRAGMA_WEAK)
Packit 0848f5
#pragma weak MPI_Win_set_attr = PMPI_Win_set_attr
Packit 0848f5
#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
Packit 0848f5
#pragma _HP_SECONDARY_DEF PMPI_Win_set_attr  MPI_Win_set_attr
Packit 0848f5
#elif defined(HAVE_PRAGMA_CRI_DUP)
Packit 0848f5
#pragma _CRI duplicate MPI_Win_set_attr as PMPI_Win_set_attr
Packit 0848f5
#elif defined(HAVE_WEAK_ATTRIBUTE)
Packit 0848f5
int MPI_Win_set_attr(MPI_Win win, int win_keyval, void *attribute_val) __attribute__((weak,alias("PMPI_Win_set_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_set_attr
Packit 0848f5
#define MPI_Win_set_attr PMPI_Win_set_attr
Packit 0848f5
Packit 0848f5
#undef FUNCNAME
Packit 0848f5
#define FUNCNAME MPIR_WinSetAttr
Packit 0848f5
int MPIR_WinSetAttr( MPI_Win win, int win_keyval, void *attribute_val, 
Packit 0848f5
		     MPIR_AttrType attrType )
Packit 0848f5
{
Packit 0848f5
    static const char FCNAME[] = "MPI_Win_set_attr";
Packit 0848f5
    int mpi_errno = MPI_SUCCESS;
Packit 0848f5
    MPID_Win *win_ptr = NULL;
Packit 0848f5
    MPID_Keyval *keyval_ptr = NULL;
Packit 0848f5
    MPID_Attribute *p, **old_p;
Packit 0848f5
    MPID_MPI_STATE_DECL(MPID_STATE_MPIR_WIN_SET_ATTR);
Packit 0848f5
Packit 0848f5
    MPIR_ERRTEST_INITIALIZED_ORDIE();
Packit 0848f5
    
Packit 0848f5
    /* The thread lock prevents a valid attr delete on the same window
Packit 0848f5
       but in a different thread from causing problems */
Packit 0848f5
    MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
Packit 0848f5
    MPID_MPI_FUNC_ENTER(MPID_STATE_MPIR_WIN_SET_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
	    MPIR_ERRTEST_KEYVAL_PERM(win_keyval, mpi_errno);
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
    MPID_Keyval_get_ptr( win_keyval, keyval_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
	    /* Validate keyval */
Packit 0848f5
	    MPID_Keyval_valid_ptr( keyval_ptr, mpi_errno );
Packit 0848f5
            if (mpi_errno) goto fn_fail;
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
    /* Look for attribute.  They are ordered by keyval handle.  This uses 
Packit 0848f5
       a simple linear list algorithm because few applications use more than a 
Packit 0848f5
       handful of attributes */
Packit 0848f5
    
Packit 0848f5
    old_p = &win_ptr->attributes;
Packit 0848f5
    p = win_ptr->attributes;
Packit 0848f5
    while (p)
Packit 0848f5
    {
Packit 0848f5
	if (p->keyval->handle == keyval_ptr->handle)
Packit 0848f5
	{
Packit 0848f5
	    /* If found, call the delete function before replacing the 
Packit 0848f5
	       attribute */
Packit 0848f5
	    mpi_errno = MPIR_Call_attr_delete( win, p );
Packit 0848f5
	    /* --BEGIN ERROR HANDLING-- */
Packit 0848f5
	    if (mpi_errno)
Packit 0848f5
	    {
Packit 0848f5
		/* FIXME : communicator of window? */
Packit 0848f5
		goto fn_fail;
Packit 0848f5
	    }
Packit 0848f5
	    /* --END ERROR HANDLING-- */
Packit 0848f5
	    p->value    = (MPID_AttrVal_t)(MPIU_Pint)attribute_val;
Packit 0848f5
	    p->attrType = attrType;
Packit 0848f5
	    /* Does not change the reference count on the keyval */
Packit 0848f5
	    break;
Packit 0848f5
	}
Packit 0848f5
	else if (p->keyval->handle > keyval_ptr->handle) {
Packit 0848f5
	    MPID_Attribute *new_p = MPID_Attr_alloc();
Packit 0848f5
	    MPIR_ERR_CHKANDJUMP1(!new_p,mpi_errno,MPI_ERR_OTHER,
Packit 0848f5
				 "**nomem", "**nomem %s", "MPID_Attribute" );
Packit 0848f5
	    new_p->keyval	 = keyval_ptr;
Packit 0848f5
	    new_p->attrType      = attrType;
Packit 0848f5
	    new_p->pre_sentinal	 = 0;
Packit 0848f5
	    new_p->value	 = (MPID_AttrVal_t)(MPIU_Pint)attribute_val;
Packit 0848f5
	    new_p->post_sentinal = 0;
Packit 0848f5
	    new_p->next		 = p->next;
Packit 0848f5
	    MPIR_Keyval_add_ref( keyval_ptr );
Packit 0848f5
	    p->next		 = new_p;
Packit 0848f5
	    break;
Packit 0848f5
	}
Packit 0848f5
	old_p = &p->next;
Packit 0848f5
	p = p->next;
Packit 0848f5
    }
Packit 0848f5
    if (!p)
Packit 0848f5
    {
Packit 0848f5
	MPID_Attribute *new_p = MPID_Attr_alloc();
Packit 0848f5
	MPIR_ERR_CHKANDJUMP1(!new_p,mpi_errno,MPI_ERR_OTHER,
Packit 0848f5
			     "**nomem", "**nomem %s", "MPID_Attribute" );
Packit 0848f5
	/* Did not find in list.  Add at end */
Packit 0848f5
	new_p->attrType      = attrType;
Packit 0848f5
	new_p->keyval	     = keyval_ptr;
Packit 0848f5
	new_p->pre_sentinal  = 0;
Packit 0848f5
	new_p->value	     = (MPID_AttrVal_t)(MPIU_Pint)attribute_val;
Packit 0848f5
	new_p->post_sentinal = 0;
Packit 0848f5
	new_p->next	     = 0;
Packit 0848f5
	MPIR_Keyval_add_ref( keyval_ptr );
Packit 0848f5
	*old_p		     = new_p;
Packit 0848f5
    }
Packit 0848f5
    
Packit 0848f5
    /* Here is where we could add a hook for the device to detect attribute
Packit 0848f5
       value changes, using something like
Packit 0848f5
       MPID_Dev_win_attr_hook( win_ptr, keyval, attribute_val );
Packit 0848f5
    */
Packit 0848f5
    
Packit 0848f5
    /* ... end of body of routine ... */
Packit 0848f5
Packit 0848f5
  fn_exit:
Packit 0848f5
    MPID_MPI_FUNC_EXIT(MPID_STATE_MPIR_WIN_SET_ATTR);
Packit 0848f5
    MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX); 
Packit 0848f5
    return mpi_errno;
Packit 0848f5
Packit 0848f5
  fn_fail:
Packit 0848f5
    /* --BEGIN ERROR HANDLING-- */
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, "**mpi_win_set_attr", 
Packit 0848f5
	    "**mpi_win_set_attr %W %d %p", win, win_keyval, attribute_val);
Packit 0848f5
    }
Packit 0848f5
#   endif
Packit 0848f5
    mpi_errno = MPIR_Err_return_win( win_ptr, FCNAME, mpi_errno );
Packit 0848f5
    goto fn_exit;
Packit 0848f5
    /* --END ERROR HANDLING-- */
Packit 0848f5
}
Packit 0848f5
#endif
Packit 0848f5
Packit 0848f5
#undef FUNCNAME
Packit 0848f5
#define FUNCNAME MPI_Win_set_attr
Packit 0848f5
#undef FCNAME
Packit 0848f5
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit 0848f5
Packit 0848f5
/*@
Packit 0848f5
   MPI_Win_set_attr - Stores attribute value associated with a key
Packit 0848f5
Packit 0848f5
Input Parameters:
Packit 0848f5
+ win - MPI window object to which attribute will be attached (handle) 
Packit 0848f5
. win_keyval - key value, as returned by  'MPI_Win_create_keyval' (integer)
Packit 0848f5
- attribute_val - attribute value 
Packit 0848f5
Packit 0848f5
Notes:
Packit 0848f5
Packit 0848f5
The type of the attribute value depends on whether C or Fortran is being used.
Packit 0848f5
In C, an attribute value is a pointer ('void *'); in Fortran, it is an 
Packit 0848f5
address-sized integer.
Packit 0848f5
Packit 0848f5
If an attribute is already present, the delete function (specified when the
Packit 0848f5
corresponding keyval was created) will be called.
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
@*/
Packit 0848f5
int MPI_Win_set_attr(MPI_Win win, int win_keyval, void *attribute_val)
Packit 0848f5
{
Packit 0848f5
    int mpi_errno = MPI_SUCCESS;
Packit 0848f5
    MPID_MPI_STATE_DECL(MPID_STATE_MPI_WIN_SET_ATTR);
Packit 0848f5
    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_WIN_SET_ATTR);
Packit 0848f5
Packit 0848f5
    MPIR_ERRTEST_INITIALIZED_ORDIE();
Packit 0848f5
    
Packit 0848f5
    /* ... body of routine ...  */
Packit 0848f5
    mpi_errno = MPIR_WinSetAttr( win, win_keyval, attribute_val, 
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_SET_ATTR);
Packit 0848f5
    return mpi_errno;
Packit 0848f5
Packit 0848f5
  fn_fail:
Packit 0848f5
    /* --BEGIN ERROR HANDLING-- */
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, "**mpi_win_set_attr", 
Packit 0848f5
	    "**mpi_win_set_attr %W %d %p", win, win_keyval, attribute_val);
Packit 0848f5
    }
Packit 0848f5
#   endif
Packit 0848f5
    goto fn_exit;
Packit 0848f5
    /* --END ERROR HANDLING-- */
Packit 0848f5
}