|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
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 |
* Portions of this code were written by Microsoft. Those portions are
|
|
Packit Service |
c5cf8c |
* Copyright (c) 2007 Microsoft Corporation. Microsoft grants
|
|
Packit Service |
c5cf8c |
* permission to use, reproduce, prepare derivative works, and to
|
|
Packit Service |
c5cf8c |
* redistribute to others. The code is licensed "as is." The User
|
|
Packit Service |
c5cf8c |
* bears the risk of using it. Microsoft gives no express warranties,
|
|
Packit Service |
c5cf8c |
* guarantees or conditions. To the extent permitted by law, Microsoft
|
|
Packit Service |
c5cf8c |
* excludes the implied warranties of merchantability, fitness for a
|
|
Packit Service |
c5cf8c |
* particular purpose and non-infringement.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpiimpl.h"
|
|
Packit Service |
c5cf8c |
#include "attr.h"
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Keyvals. These are handled just like the other opaque objects in MPICH
|
|
Packit Service |
c5cf8c |
* The predefined keyvals (and their associated attributes) are handled
|
|
Packit Service |
c5cf8c |
* separately, without using the keyval
|
|
Packit Service |
c5cf8c |
* storage
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifndef MPID_KEYVAL_PREALLOC
|
|
Packit Service |
c5cf8c |
#define MPID_KEYVAL_PREALLOC 16
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Preallocated keyval objects */
|
|
Packit Service |
c5cf8c |
MPII_Keyval MPII_Keyval_direct[MPID_KEYVAL_PREALLOC] = { {0}
|
|
Packit Service |
c5cf8c |
};
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Object_alloc_t MPII_Keyval_mem = { 0, 0, 0, 0, MPIR_KEYVAL,
|
|
Packit Service |
c5cf8c |
sizeof(MPII_Keyval),
|
|
Packit Service |
c5cf8c |
MPII_Keyval_direct,
|
|
Packit Service |
c5cf8c |
MPID_KEYVAL_PREALLOC,
|
|
Packit Service |
c5cf8c |
};
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifndef MPIR_ATTR_PREALLOC
|
|
Packit Service |
c5cf8c |
#define MPIR_ATTR_PREALLOC 32
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Preallocated keyval objects */
|
|
Packit Service |
c5cf8c |
MPIR_Attribute MPID_Attr_direct[MPIR_ATTR_PREALLOC] = { {0}
|
|
Packit Service |
c5cf8c |
};
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Object_alloc_t MPID_Attr_mem = { 0, 0, 0, 0, MPIR_ATTR,
|
|
Packit Service |
c5cf8c |
sizeof(MPIR_Attribute),
|
|
Packit Service |
c5cf8c |
MPID_Attr_direct,
|
|
Packit Service |
c5cf8c |
MPIR_ATTR_PREALLOC,
|
|
Packit Service |
c5cf8c |
};
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Provides a way to trap all attribute allocations when debugging leaks. */
|
|
Packit Service |
c5cf8c |
MPIR_Attribute *MPID_Attr_alloc(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPIR_Attribute *attr = (MPIR_Attribute *) MPIR_Handle_obj_alloc(&MPID_Attr_mem);
|
|
Packit Service |
c5cf8c |
/* attributes don't have refcount semantics, but let's keep valgrind and
|
|
Packit Service |
c5cf8c |
* the debug logging pacified */
|
|
Packit Service |
c5cf8c |
MPIR_Assert(attr != NULL);
|
|
Packit Service |
c5cf8c |
MPIR_Object_set_ref(attr, 0);
|
|
Packit Service |
c5cf8c |
return attr;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void MPID_Attr_free(MPIR_Attribute * attr_ptr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPIR_Handle_obj_free(&MPID_Attr_mem, attr_ptr);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIR_Call_attr_delete
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME MPL_QUOTE(FUNCNAME)
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
This function deletes a single attribute.
|
|
Packit Service |
c5cf8c |
It is called by both the function to delete a list and attribute set/put
|
|
Packit Service |
c5cf8c |
val. Return the return code from the delete function; 0 if there is no
|
|
Packit Service |
c5cf8c |
delete function.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Even though there are separate keyvals for communicators, types, and files,
|
|
Packit Service |
c5cf8c |
we can use the same function because the handle for these is always an int
|
|
Packit Service |
c5cf8c |
in MPICH.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Note that this simply invokes the attribute delete function. It does not
|
|
Packit Service |
c5cf8c |
remove the attribute from the list of attributes.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIR_Call_attr_delete(int handle, MPIR_Attribute * attr_p)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int rc;
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
MPII_Keyval *kv = attr_p->keyval;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (kv->delfn.user_function == NULL)
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = kv->delfn.proxy(kv->delfn.user_function,
|
|
Packit Service |
c5cf8c |
handle,
|
|
Packit Service |
c5cf8c |
attr_p->keyval->handle,
|
|
Packit Service |
c5cf8c |
attr_p->attrType,
|
|
Packit Service |
c5cf8c |
(void *) (intptr_t) attr_p->value, attr_p->keyval->extra_state);
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
#if MPICH_ERROR_MSG_LEVEL < MPICH_ERROR_MSG__ALL
|
|
Packit Service |
c5cf8c |
/* If rc is a valid error class, then return that.
|
|
Packit Service |
c5cf8c |
* Note that it may be a dynamic error class */
|
|
Packit Service |
c5cf8c |
/* AMBIGUOUS: This is an ambiguity in the MPI standard: What is the
|
|
Packit Service |
c5cf8c |
* error value returned from the user-provided routine? Particularly
|
|
Packit Service |
c5cf8c |
* with the MPI-2 feature of user-defined error codes, the
|
|
Packit Service |
c5cf8c |
* user expectation is probably that the user-provided error code
|
|
Packit Service |
c5cf8c |
* is returned. */
|
|
Packit Service |
c5cf8c |
mpi_errno = rc;
|
|
Packit Service |
c5cf8c |
#else
|
|
Packit Service |
c5cf8c |
mpi_errno =
|
|
Packit Service |
c5cf8c |
MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
|
|
Packit Service |
c5cf8c |
"**user", "**userdel %d", rc);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
goto fn_fail;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
fn_fail:
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
This function copies a single attribute.
|
|
Packit Service |
c5cf8c |
It is called by the function to copy a list of attribute
|
|
Packit Service |
c5cf8c |
Return the return code from the copy function; MPI_SUCCESS if there is
|
|
Packit Service |
c5cf8c |
no copy function.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Even though there are separate keyvals for communicators, types, and files,
|
|
Packit Service |
c5cf8c |
we can use the same function because the handle for these is always an int
|
|
Packit Service |
c5cf8c |
in MPICH.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Note that this simply invokes the attribute copy function.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIR_Call_attr_copy
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME MPL_QUOTE(FUNCNAME)
|
|
Packit Service |
c5cf8c |
int MPIR_Call_attr_copy(int handle, MPIR_Attribute * attr_p, void **value_copy, int *flag)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
int rc;
|
|
Packit Service |
c5cf8c |
MPII_Keyval *kv = attr_p->keyval;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (kv->copyfn.user_function == NULL)
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = kv->copyfn.proxy(kv->copyfn.user_function,
|
|
Packit Service |
c5cf8c |
handle,
|
|
Packit Service |
c5cf8c |
attr_p->keyval->handle,
|
|
Packit Service |
c5cf8c |
attr_p->keyval->extra_state,
|
|
Packit Service |
c5cf8c |
attr_p->attrType, (void *) (intptr_t) attr_p->value, value_copy, flag);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
#if MPICH_ERROR_MSG_LEVEL < MPICH_ERROR_MSG__ALL
|
|
Packit Service |
c5cf8c |
mpi_errno = rc;
|
|
Packit Service |
c5cf8c |
#else
|
|
Packit Service |
c5cf8c |
mpi_errno =
|
|
Packit Service |
c5cf8c |
MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
|
|
Packit Service |
c5cf8c |
"**user", "**usercopy %d", rc);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
goto fn_fail;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
fn_fail:
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIR_Attr_dup_list
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME MPL_QUOTE(FUNCNAME)
|
|
Packit Service |
c5cf8c |
/* Routine to duplicate an attribute list */
|
|
Packit Service |
c5cf8c |
int MPIR_Attr_dup_list(int handle, MPIR_Attribute * old_attrs, MPIR_Attribute ** new_attr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPIR_Attribute *p, *new_p, **next_new_attr_ptr = new_attr;
|
|
Packit Service |
c5cf8c |
void *new_value = NULL;
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (p = old_attrs; p != NULL; p = p->next) {
|
|
Packit Service |
c5cf8c |
/* call the attribute copy function (if any) */
|
|
Packit Service |
c5cf8c |
int flag = 0;
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Call_attr_copy(handle, p, &new_value, &flag;;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (mpi_errno != MPI_SUCCESS)
|
|
Packit Service |
c5cf8c |
goto fn_fail;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!flag)
|
|
Packit Service |
c5cf8c |
continue;
|
|
Packit Service |
c5cf8c |
/* If flag was returned as true, then insert this attribute into the
|
|
Packit Service |
c5cf8c |
* new list (new_attr) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* duplicate the attribute by creating new storage, copying the
|
|
Packit Service |
c5cf8c |
* attribute value, and invoking the copy function */
|
|
Packit Service |
c5cf8c |
new_p = MPID_Attr_alloc();
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (!new_p) {
|
|
Packit Service |
c5cf8c |
mpi_errno =
|
|
Packit Service |
c5cf8c |
MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__,
|
|
Packit Service |
c5cf8c |
MPI_ERR_OTHER, "**nomem", 0);
|
|
Packit Service |
c5cf8c |
goto fn_fail;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (!*new_attr) {
|
|
Packit Service |
c5cf8c |
*new_attr = new_p;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
*(next_new_attr_ptr) = new_p;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
new_p->keyval = p->keyval;
|
|
Packit Service |
c5cf8c |
/* Remember that we need this keyval */
|
|
Packit Service |
c5cf8c |
MPII_Keyval_add_ref(p->keyval);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
new_p->attrType = p->attrType;
|
|
Packit Service |
c5cf8c |
new_p->pre_sentinal = 0;
|
|
Packit Service |
c5cf8c |
/* FIXME: This is not correct in some cases (size(MPI_Aint)>
|
|
Packit Service |
c5cf8c |
* sizeof(intptr_t)) */
|
|
Packit Service |
c5cf8c |
new_p->value = (MPII_Attr_val_t) (intptr_t) new_value;
|
|
Packit Service |
c5cf8c |
new_p->post_sentinal = 0;
|
|
Packit Service |
c5cf8c |
new_p->next = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
next_new_attr_ptr = &(new_p->next);
|
|
Packit Service |
c5cf8c |
} /* for(;;) */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
fn_fail:
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIR_Attr_delete_list
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME MPL_QUOTE(FUNCNAME)
|
|
Packit Service |
c5cf8c |
/* Routine to delete an attribute list */
|
|
Packit Service |
c5cf8c |
int MPIR_Attr_delete_list(int handle, MPIR_Attribute ** attr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPIR_Attribute *p, *new_p;
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p = *attr;
|
|
Packit Service |
c5cf8c |
while (p) {
|
|
Packit Service |
c5cf8c |
/* delete the attribute by first executing the delete routine, if any,
|
|
Packit Service |
c5cf8c |
* determine the the next attribute, and recover the attributes
|
|
Packit Service |
c5cf8c |
* storage */
|
|
Packit Service |
c5cf8c |
new_p = p->next;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Check the sentinals first */
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (p->pre_sentinal != 0 || p->post_sentinal != 0) {
|
|
Packit Service |
c5cf8c |
MPIR_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**attrsentinal");
|
|
Packit Service |
c5cf8c |
/* We could keep trying to free the attributes, but for now
|
|
Packit Service |
c5cf8c |
* we'll just bag it */
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
/* For this attribute, find the delete function for the
|
|
Packit Service |
c5cf8c |
* corresponding keyval */
|
|
Packit Service |
c5cf8c |
/* Still to do: capture any error returns but continue to
|
|
Packit Service |
c5cf8c |
* process attributes */
|
|
Packit Service |
c5cf8c |
mpi_errno = MPIR_Call_attr_delete(handle, p);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* We must also remove the keyval reference. If the keyval
|
|
Packit Service |
c5cf8c |
* was freed earlier (reducing the refcount), the actual
|
|
Packit Service |
c5cf8c |
* release and free will happen here. We must free the keyval
|
|
Packit Service |
c5cf8c |
* even if the attr delete failed, as we then remove the
|
|
Packit Service |
c5cf8c |
* attribute.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int in_use;
|
|
Packit Service |
c5cf8c |
/* Decrement the use of the keyval */
|
|
Packit Service |
c5cf8c |
MPII_Keyval_release_ref(p->keyval, &in_use);
|
|
Packit Service |
c5cf8c |
if (!in_use) {
|
|
Packit Service |
c5cf8c |
MPIR_Handle_obj_free(&MPII_Keyval_mem, p->keyval);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Handle_obj_free(&MPID_Attr_mem, p);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p = new_p;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* We must zero out the attribute list pointer or we could attempt to use it
|
|
Packit Service |
c5cf8c |
* later. This normally can't happen because the communicator usually
|
|
Packit Service |
c5cf8c |
* disappears after a call to MPI_Comm_free. But if the attribute keyval
|
|
Packit Service |
c5cf8c |
* has an associated delete function that returns an error then we don't
|
|
Packit Service |
c5cf8c |
* actually free the communicator despite having freed all the attributes
|
|
Packit Service |
c5cf8c |
* associated with the communicator.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* This function is also used for Win and Type objects, but the idea is the
|
|
Packit Service |
c5cf8c |
* same in those cases as well. */
|
|
Packit Service |
c5cf8c |
*attr = NULL;
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int
|
|
Packit Service |
c5cf8c |
MPII_Attr_copy_c_proxy(MPI_Comm_copy_attr_function * user_function,
|
|
Packit Service |
c5cf8c |
int handle,
|
|
Packit Service |
c5cf8c |
int keyval,
|
|
Packit Service |
c5cf8c |
void *extra_state,
|
|
Packit Service |
c5cf8c |
MPIR_Attr_type attrib_type, void *attrib, void **attrib_copy, int *flag)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
void *attrib_val = NULL;
|
|
Packit Service |
c5cf8c |
int ret;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Make sure that the attribute value is delieverd as a pointer */
|
|
Packit Service |
c5cf8c |
if (MPII_ATTR_KIND(attrib_type) == MPII_ATTR_KIND(MPIR_ATTR_INT)) {
|
|
Packit Service |
c5cf8c |
attrib_val = &attrib;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
attrib_val = attrib;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* user functions might call other MPI functions, so we need to
|
|
Packit Service |
c5cf8c |
* release the lock here. This is safe to do as GLOBAL is not at
|
|
Packit Service |
c5cf8c |
* all recursive in our implementation. */
|
|
Packit Service |
c5cf8c |
MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
|
|
Packit Service |
c5cf8c |
ret = user_function(handle, keyval, extra_state, attrib_val, attrib_copy, flag);
|
|
Packit Service |
c5cf8c |
MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return ret;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int
|
|
Packit Service |
c5cf8c |
MPII_Attr_delete_c_proxy(MPI_Comm_delete_attr_function * user_function,
|
|
Packit Service |
c5cf8c |
int handle,
|
|
Packit Service |
c5cf8c |
int keyval, MPIR_Attr_type attrib_type, void *attrib, void *extra_state)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
void *attrib_val = NULL;
|
|
Packit Service |
c5cf8c |
int ret;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Make sure that the attribute value is delieverd as a pointer */
|
|
Packit Service |
c5cf8c |
if (MPII_ATTR_KIND(attrib_type) == MPII_ATTR_KIND(MPIR_ATTR_INT))
|
|
Packit Service |
c5cf8c |
attrib_val = &attrib;
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
attrib_val = attrib;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* user functions might call other MPI functions, so we need to
|
|
Packit Service |
c5cf8c |
* release the lock here. This is safe to do as GLOBAL is not at
|
|
Packit Service |
c5cf8c |
* all recursive in our implementation. */
|
|
Packit Service |
c5cf8c |
MPID_THREAD_CS_EXIT(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
|
|
Packit Service |
c5cf8c |
ret = user_function(handle, keyval, attrib_val, extra_state);
|
|
Packit Service |
c5cf8c |
MPID_THREAD_CS_ENTER(GLOBAL, MPIR_THREAD_GLOBAL_ALLFUNC_MUTEX);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return ret;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: Missing routine description */
|
|
Packit Service |
c5cf8c |
void
|
|
Packit Service |
c5cf8c |
MPII_Keyval_set_proxy(int keyval,
|
|
Packit Service |
c5cf8c |
MPII_Attr_copy_proxy copy_proxy, MPII_Attr_delete_proxy delete_proxy)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPII_Keyval *keyval_ptr;
|
|
Packit Service |
c5cf8c |
MPII_Keyval_get_ptr(keyval, keyval_ptr);
|
|
Packit Service |
c5cf8c |
if (keyval_ptr == NULL)
|
|
Packit Service |
c5cf8c |
return;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
keyval_ptr->copyfn.proxy = copy_proxy;
|
|
Packit Service |
c5cf8c |
keyval_ptr->delfn.proxy = delete_proxy;
|
|
Packit Service |
c5cf8c |
}
|