Blame src/mpi/attr/comm_create_keyval.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
 * Portions of this code were written by Microsoft. Those portions are
Packit 0848f5
 * Copyright (c) 2007 Microsoft Corporation. Microsoft grants
Packit 0848f5
 * permission to use, reproduce, prepare derivative works, and to
Packit 0848f5
 * redistribute to others. The code is licensed "as is." The User
Packit 0848f5
 * bears the risk of using it. Microsoft gives no express warranties,
Packit 0848f5
 * guarantees or conditions. To the extent permitted by law, Microsoft
Packit 0848f5
 * excludes the implied warranties of merchantability, fitness for a
Packit 0848f5
 * particular purpose and non-infringement.
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_Comm_create_keyval */
Packit 0848f5
#if defined(HAVE_PRAGMA_WEAK)
Packit 0848f5
#pragma weak MPI_Comm_create_keyval = PMPI_Comm_create_keyval
Packit 0848f5
#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
Packit 0848f5
#pragma _HP_SECONDARY_DEF PMPI_Comm_create_keyval  MPI_Comm_create_keyval
Packit 0848f5
#elif defined(HAVE_PRAGMA_CRI_DUP)
Packit 0848f5
#pragma _CRI duplicate MPI_Comm_create_keyval as PMPI_Comm_create_keyval
Packit 0848f5
#elif defined(HAVE_WEAK_ATTRIBUTE)
Packit 0848f5
int MPI_Comm_create_keyval(MPI_Comm_copy_attr_function *comm_copy_attr_fn,
Packit 0848f5
                           MPI_Comm_delete_attr_function *comm_delete_attr_fn, int *comm_keyval,
Packit 0848f5
                           void *extra_state) __attribute__((weak,alias("PMPI_Comm_create_keyval")));
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_Comm_create_keyval
Packit 0848f5
#define MPI_Comm_create_keyval PMPI_Comm_create_keyval
Packit 0848f5
Packit 0848f5
#undef FUNCNAME
Packit 0848f5
#define FUNCNAME MPIR_Comm_create_keyval_impl
Packit 0848f5
#undef FCNAME
Packit 0848f5
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit 0848f5
int MPIR_Comm_create_keyval_impl(MPI_Comm_copy_attr_function *comm_copy_attr_fn,
Packit 0848f5
                                 MPI_Comm_delete_attr_function *comm_delete_attr_fn,
Packit 0848f5
                                 int *comm_keyval, void *extra_state)
Packit 0848f5
{
Packit 0848f5
    int mpi_errno = MPI_SUCCESS;
Packit 0848f5
    MPID_Keyval *keyval_ptr;
Packit 0848f5
        
Packit 0848f5
    keyval_ptr = (MPID_Keyval *)MPIU_Handle_obj_alloc( &MPID_Keyval_mem );
Packit 0848f5
    MPIR_ERR_CHKANDJUMP(!keyval_ptr, mpi_errno, MPI_ERR_OTHER,"**nomem");
Packit 0848f5
Packit 0848f5
    /* Initialize the attribute dup function */
Packit 0848f5
    if (!MPIR_Process.attr_dup) {
Packit 0848f5
	MPIR_Process.attr_dup  = MPIR_Attr_dup_list;
Packit 0848f5
	MPIR_Process.attr_free = MPIR_Attr_delete_list;
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    /* The handle encodes the keyval kind.  Modify it to have the correct
Packit 0848f5
       field */
Packit 0848f5
    keyval_ptr->handle           = (keyval_ptr->handle & ~(0x03c00000)) |
Packit 0848f5
	                           (MPID_COMM << 22);
Packit 0848f5
    MPIU_Object_set_ref(keyval_ptr,1);
Packit 0848f5
    keyval_ptr->was_freed        = 0;
Packit 0848f5
    keyval_ptr->kind	         = MPID_COMM;
Packit 0848f5
    keyval_ptr->extra_state      = extra_state;
Packit 0848f5
    keyval_ptr->copyfn.user_function = comm_copy_attr_fn;
Packit 0848f5
    keyval_ptr->copyfn.proxy = MPIR_Attr_copy_c_proxy;
Packit 0848f5
    keyval_ptr->delfn.user_function = comm_delete_attr_fn;
Packit 0848f5
    keyval_ptr->delfn.proxy = MPIR_Attr_delete_c_proxy;
Packit 0848f5
Packit 0848f5
    MPID_OBJ_PUBLISH_HANDLE(*comm_keyval, keyval_ptr->handle);
Packit 0848f5
Packit 0848f5
 fn_exit:
Packit 0848f5
    return mpi_errno;
Packit 0848f5
 fn_fail:
Packit 0848f5
Packit 0848f5
    goto fn_exit;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
#endif
Packit 0848f5
Packit 0848f5
#undef FUNCNAME
Packit 0848f5
#define FUNCNAME MPI_Comm_create_keyval
Packit 0848f5
#undef FCNAME
Packit 0848f5
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit 0848f5
/*@
Packit 0848f5
   MPI_Comm_create_keyval - Create a new attribute key 
Packit 0848f5
Packit 0848f5
Input Parameters:
Packit 0848f5
+ comm_copy_attr_fn - Copy callback function for 'keyval'
Packit 0848f5
. comm_delete_attr_fn - Delete callback function for 'keyval'
Packit 0848f5
- extra_state - Extra state for callback functions 
Packit 0848f5
Packit 0848f5
Output Parameters:
Packit 0848f5
. comm_keyval - key value for future access (integer) 
Packit 0848f5
Packit 0848f5
Notes:
Packit 0848f5
Key values are global (available for any and all communicators).
Packit 0848f5
Packit 0848f5
Default copy and delete functions are available.  These are
Packit 0848f5
+ MPI_COMM_NULL_COPY_FN   - empty copy function
Packit 0848f5
. MPI_COMM_NULL_DELETE_FN - empty delete function
Packit 0848f5
- MPI_COMM_DUP_FN         - simple dup function
Packit 0848f5
Packit 0848f5
There are subtle differences between C and Fortran that require that the
Packit 0848f5
copy_fn be written in the same language from which 'MPI_Comm_create_keyval'
Packit 0848f5
is called.
Packit 0848f5
This should not be a problem for most users; only programmers using both
Packit 0848f5
Fortran and C in the same program need to be sure that they follow this rule.
Packit 0848f5
Packit 0848f5
.N AttrErrReturn
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
Packit 0848f5
.seealso MPI_Comm_free_keyval
Packit 0848f5
@*/
Packit 0848f5
int MPI_Comm_create_keyval(MPI_Comm_copy_attr_function *comm_copy_attr_fn, 
Packit 0848f5
			   MPI_Comm_delete_attr_function *comm_delete_attr_fn, 
Packit 0848f5
			   int *comm_keyval, void *extra_state)
Packit 0848f5
{
Packit 0848f5
    int mpi_errno = MPI_SUCCESS;
Packit 0848f5
    MPID_MPI_STATE_DECL(MPID_STATE_MPI_COMM_CREATE_KEYVAL);
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_MPI_COMM_CREATE_KEYVAL);
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
	    MPIR_ERRTEST_ARGNULL(comm_keyval, "comm_keyval", 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
    mpi_errno = MPIR_Comm_create_keyval_impl(comm_copy_attr_fn, comm_delete_attr_fn, comm_keyval, extra_state);
Packit 0848f5
    if (mpi_errno) goto fn_fail;
Packit 0848f5
    
Packit 0848f5
    /* ... end of body of routine ... */
Packit 0848f5
Packit 0848f5
  fn_exit:
Packit 0848f5
    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_COMM_CREATE_KEYVAL);
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_comm_create_keyval",
Packit 0848f5
	    "**mpi_comm_create_keyval %p %p %p %p", comm_copy_attr_fn, comm_delete_attr_fn, comm_keyval, extra_state);
Packit 0848f5
    }
Packit 0848f5
#   endif
Packit 0848f5
    mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno );
Packit 0848f5
    goto fn_exit;
Packit 0848f5
    /* --END ERROR HANDLING-- */
Packit 0848f5
}