-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/attr/attrutil.c
-: 0:Graph:attrutil.gcno
-: 0:Data:attrutil.gcda
-: 0:Runs:2438
-: 0:Programs:559
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: * (C) 2001 by Argonne National Laboratory.
-: 4: * See COPYRIGHT in top-level directory.
-: 5: */
-: 6:
-: 7:#include "mpiimpl.h"
-: 8:#include "attr.h"
-: 9:/*
-: 10: * Keyvals. These are handled just like the other opaque objects in MPICH
-: 11: * The predefined keyvals (and their associated attributes) are handled
-: 12: * separately, without using the keyval
-: 13: * storage
-: 14: */
-: 15:
-: 16:#ifndef MPID_KEYVAL_PREALLOC
-: 17:#define MPID_KEYVAL_PREALLOC 16
-: 18:#endif
-: 19:
-: 20:/* Preallocated keyval objects */
-: 21:MPID_Keyval MPID_Keyval_direct[MPID_KEYVAL_PREALLOC] = { {0} };
-: 22:MPIU_Object_alloc_t MPID_Keyval_mem = { 0, 0, 0, 0, MPID_KEYVAL,
-: 23: sizeof(MPID_Keyval),
-: 24: MPID_Keyval_direct,
-: 25: MPID_KEYVAL_PREALLOC, };
-: 26:
-: 27:#ifndef MPID_ATTR_PREALLOC
-: 28:#define MPID_ATTR_PREALLOC 32
-: 29:#endif
-: 30:
-: 31:/* Preallocated keyval objects */
-: 32:MPID_Attribute MPID_Attr_direct[MPID_ATTR_PREALLOC] = { {0} };
-: 33:MPIU_Object_alloc_t MPID_Attr_mem = { 0, 0, 0, 0, MPID_ATTR,
-: 34: sizeof(MPID_Attribute),
-: 35: MPID_Attr_direct,
-: 36: MPID_ATTR_PREALLOC, };
-: 37:
-: 38:/* Provides a way to trap all attribute allocations when debugging leaks. */
-: 39:MPID_Attribute *MPID_Attr_alloc(void)
6586: 40:{
6586: 41: MPID_Attribute *attr = (MPID_Attribute *)MPIU_Handle_obj_alloc(&MPID_Attr_mem);
-: 42: /* attributes don't have refcount semantics, but let's keep valgrind and
-: 43: * the debug logging pacified */
6586: 44: MPIU_Object_set_ref(attr, 0);
6586: 45: return attr;
-: 46:}
-: 47:
-: 48:void MPID_Attr_free(MPID_Attribute *attr_ptr)
177: 49:{
177: 50: MPIU_Handle_obj_free(&MPID_Attr_mem, attr_ptr);
177: 51:}
-: 52:
-: 53:#undef FUNCNAME
-: 54:#define FUNCNAME MPIR_Call_attr_delete
-: 55:#undef FCNAME
-: 56:#define FCNAME MPIU_QUOTE(FUNCNAME)
-: 57:/*
-: 58: This function deletes a single attribute.
-: 59: It is called by both the function to delete a list and attribute set/put
-: 60: val. Return the return code from the delete function; 0 if there is no
-: 61: delete function.
-: 62:
-: 63: Even though there are separate keyvals for communicators, types, and files,
-: 64: we can use the same function because the handle for these is always an int
-: 65: in MPICH2.
-: 66:
-: 67: Note that this simply invokes the attribute delete function. It does not
-: 68: remove the attribute from the list of attributes.
-: 69:*/
-: 70:int MPIR_Call_attr_delete( int handle, MPID_Attribute *attr_p )
6738: 71:{
-: 72: int rc;
6738: 73: int mpi_errno = MPI_SUCCESS;
6738: 74: MPID_Keyval* kv = attr_p->keyval;
-: 75:
6738: 76: MPIU_THREADPRIV_DECL;
-: 77:
6738: 78: MPIU_THREADPRIV_GET;
-: 79:
6738: 80: MPIR_Nest_incr();
-: 81:
6738: 82: if(kv->delfn.user_function == NULL)
193: 83: goto fn_exit;
-: 84:
6545: 85: rc = kv->delfn.proxy(
-: 86: kv->delfn.user_function,
-: 87: handle,
-: 88: attr_p->keyval->handle,
-: 89: attr_p->attrType,
-: 90: (void *)attr_p->value,
-: 91: attr_p->keyval->extra_state
-: 92: );
|
-: 93: /* --BEGIN ERROR HANDLING-- */
6545: 94: if(rc != 0){
12: 95: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**user", "**userdel %d", rc);
12: 96: goto fn_fail;
-: 97: }
-: 98: /* --END ERROR HANDLING-- */
-: 99:
|
6738: 100: fn_exit:
6738: 101: MPIR_Nest_decr();
6738: 102: return mpi_errno;
|
-: 103: fn_fail:
-: 104: goto fn_exit;
-: 105:}
-: 106:
-: 107:/*
-: 108: This function copies a single attribute.
-: 109: It is called by the function to copy a list of attribute
-: 110: Return the return code from the copy function; MPI_SUCCESS if there is
-: 111: no copy function.
-: 112:
-: 113: Even though there are separate keyvals for communicators, types, and files,
-: 114: we can use the same function because the handle for these is always an int
-: 115: in MPICH2.
-: 116:
-: 117: Note that this simply invokes the attribute copy function.
-: 118:*/
-: 119:#undef FUNCNAME
-: 120:#define FUNCNAME MPIR_Call_attr_copy
-: 121:#undef FCNAME
-: 122:#define FCNAME MPIU_QUOTE(FUNCNAME)
-: 123:int MPIR_Call_attr_copy( int handle, MPID_Attribute *attr_p, void** value_copy, int* flag)
|
5140: 124:{
5140: 125: int mpi_errno = MPI_SUCCESS;
-: 126: int rc;
5140: 127: MPID_Keyval* kv = attr_p->keyval;
-: 128:
5140: 129: MPIU_THREADPRIV_DECL;
-: 130:
5140: 131: MPIU_THREADPRIV_GET;
-: 132:
5140: 133: MPIR_Nest_incr();
-: 134:
5140: 135: if(kv->copyfn.user_function == NULL)
1004: 136: goto fn_exit;
-: 137:
4136: 138: rc = kv->copyfn.proxy(
-: 139: kv->copyfn.user_function,
-: 140: handle,
-: 141: attr_p->keyval->handle,
-: 142: attr_p->keyval->extra_state,
-: 143: attr_p->attrType,
-: 144: (void *)attr_p->value,
-: 145: value_copy,
-: 146: flag
-: 147: );
-: 148:
|
-: 149: /* --BEGIN ERROR HANDLING-- */
4136: 150: if(rc != 0){
13: 151: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**user", "**usercopy %d", rc);
13: 152: goto fn_fail;
-: 153: }
-: 154: /* --END ERROR HANDLING-- */
|
5140: 155:fn_exit:
5140: 156: MPIR_Nest_decr();
5140: 157: return mpi_errno;
|
-: 158:fn_fail:
-: 159: goto fn_exit;
-: 160:}
-: 161:
-: 162:#undef FUNCNAME
-: 163:#define FUNCNAME MPIR_Attr_dup_list
-: 164:#undef FCNAME
-: 165:#define FCNAME MPIU_QUOTE(FUNCNAME)
-: 166:/* Routine to duplicate an attribute list */
-: 167:int MPIR_Attr_dup_list( int handle, MPID_Attribute *old_attrs,
-: 168: MPID_Attribute **new_attr )
|
4700: 169:{
4700: 170: MPID_Attribute *p, *new_p, **next_new_attr_ptr=new_attr;
4700: 171: void* new_value = NULL;
4700: 172: int mpi_errno = MPI_SUCCESS;
-: 173:
9827: 174: for(p = old_attrs; p != NULL; p = p->next)
-: 175: {
-: 176: /* call the attribute copy function (if any) */
5140: 177: int flag = 0;
5140: 178: mpi_errno = MPIR_Call_attr_copy(
-: 179: handle,
-: 180: p,
-: 181: &new_value,
-: 182: &flag
-: 183: );
-: 184:
5140: 185: if(mpi_errno != MPI_SUCCESS)
|
13: 186: goto fn_fail;
-: 187:
|
5127: 188: if(!flag)
1020: 189: continue;
-: 190: /* If flag was returned as true, then insert this attribute into the
-: 191: new list (new_attr) */
-: 192:
-: 193: /* duplicate the attribute by creating new storage, copying the
-: 194: attribute value, and invoking the copy function */
4107: 195: new_p = MPID_Attr_alloc();
|
-: 196: /* --BEGIN ERROR HANDLING-- */
4107: 197: if (!new_p){
#####: 198: mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0 );
#####: 199: goto fn_fail;
-: 200: }
-: 201: /* --END ERROR HANDLING-- */
|
4107: 202: if(!*new_attr){
4107: 203: *new_attr = new_p;
-: 204: }
4107: 205: *(next_new_attr_ptr) = new_p;
-: 206:
4107: 207: new_p->keyval = p->keyval;
-: 208: /* Remember that we need this keyval */
4107: 209: MPIR_Keyval_add_ref(p->keyval);
-: 210:
4107: 211: new_p->attrType = p->attrType;
4107: 212: new_p->pre_sentinal = 0;
4107: 213: new_p->value = (MPID_AttrVal_t)new_value;
4107: 214: new_p->post_sentinal = 0;
4107: 215: new_p->next = 0;
-: 216:
4107: 217: next_new_attr_ptr = &(new_p->next);
-: 218: } /* for(;;) */
-: 219:
4700: 220: fn_exit:
4700: 221: return mpi_errno;
|
-: 222: fn_fail:
-: 223: goto fn_exit;
-: 224:}
-: 225:
-: 226:#undef FUNCNAME
-: 227:#define FUNCNAME MPIR_Attr_delete_list
-: 228:#undef FCNAME
-: 229:#define FCNAME MPIU_QUOTE(FUNCNAME)
-: 230:/* Routine to delete an attribute list */
-: 231:int MPIR_Attr_delete_list( int handle, MPID_Attribute **attr )
|
5996: 232:{
-: 233: MPID_Attribute *p, *new_p;
5996: 234: int mpi_errno = MPI_SUCCESS;
-: 235:
5996: 236: p = *attr;
18365: 237: while (p) {
-: 238: /* delete the attribute by first executing the delete routine, if any,
-: 239: determine the the next attribute, and recover the attributes
-: 240: storage */
6373: 241: new_p = p->next;
-: 242:
-: 243: /* Check the sentinals first */
|
-: 244: /* --BEGIN ERROR HANDLING-- */
6373: 245: if (p->pre_sentinal != 0 || p->post_sentinal != 0) {
#####: 246: MPIU_ERR_SET(mpi_errno,MPI_ERR_OTHER,"**attrsentinal");
-: 247: /* We could keep trying to free the attributes, but for now
-: 248: we'll just bag it */
#####: 249: return mpi_errno;
-: 250: }
-: 251: /* --END ERROR HANDLING-- */
-: 252: /* For this attribute, find the delete function for the
-: 253: corresponding keyval */
-: 254: /* Still to do: capture any error returns but continue to
-: 255: process attributes */
|
6373: 256: mpi_errno = MPIR_Call_attr_delete( handle, p );
-: 257:
-: 258: /* We must also remove the keyval reference. If the keyval
-: 259: was freed earlier (reducing the refcount), the actual
-: 260: release and free will happen here. We must free the keyval
-: 261: even if the attr delete failed, as we then remove the
-: 262: attribute.
-: 263: */
-: 264: {
-: 265: int in_use;
-: 266: /* Decrement the use of the keyval */
6373: 267: MPIR_Keyval_release_ref( p->keyval, &in_use);
6373: 268: if (!in_use) {
661: 269: MPIU_Handle_obj_free( &MPID_Keyval_mem, p->keyval );
-: 270: }
-: 271: }
-: 272:
6373: 273: MPIU_Handle_obj_free( &MPID_Attr_mem, p );
-: 274:
6373: 275: p = new_p;
-: 276: }
-: 277:
-: 278: /* We must zero out the attribute list pointer or we could attempt to use it
-: 279: later. This normally can't happen because the communicator usually
-: 280: disappears after a call to MPI_Comm_free. But if the attribute keyval
-: 281: has an associated delete function that returns an error then we don't
-: 282: actually free the communicator despite having freed all the attributes
-: 283: associated with the communicator.
-: 284:
-: 285: This function is also used for Win and Type objects, but the idea is the
-: 286: same in those cases as well. */
5996: 287: *attr = NULL;
5996: 288: return mpi_errno;
-: 289:}
-: 290:
-: 291:int
-: 292:MPIR_Attr_copy_c_proxy(
-: 293: MPI_Comm_copy_attr_function* user_function,
-: 294: int handle,
-: 295: int keyval,
-: 296: void* extra_state,
-: 297: MPIR_AttrType attrib_type,
-: 298: void* attrib,
-: 299: void** attrib_copy,
-: 300: int* flag
-: 301: )
4112: 302:{
4112: 303: void *attrib_val = NULL;
-: 304: /* Make sure that the attribute value is delieverd as a pointer */
4112: 305: if (MPIR_ATTR_KIND(attrib_type) == MPIR_ATTR_KIND(MPIR_ATTR_INT)){
|
#####: 306: attrib_val = &attrib;
-: 307: }
-: 308: else{
|
4112: 309: attrib_val = attrib;
-: 310: }
4112: 311: return user_function(handle, keyval, extra_state, attrib_val, attrib_copy, flag);
-: 312:}
-: 313:
-: 314:
-: 315:int
-: 316:MPIR_Attr_delete_c_proxy(
-: 317: MPI_Comm_delete_attr_function* user_function,
-: 318: int handle,
-: 319: int keyval,
-: 320: MPIR_AttrType attrib_type,
-: 321: void* attrib,
-: 322: void* extra_state
-: 323: )
6482: 324:{
6482: 325: void *attrib_val = NULL;
-: 326: /* Make sure that the attribute value is delieverd as a pointer */
6482: 327: if (MPIR_ATTR_KIND(attrib_type) == MPIR_ATTR_KIND(MPIR_ATTR_INT))
|
#####: 328: attrib_val = &attrib;
-: 329: else
|
6482: 330: attrib_val = attrib;
6482: 331: return user_function(handle, keyval, attrib_val, extra_state);
-: 332:}
-: 333:
-: 334:
-: 335:void
-: 336:MPIR_Keyval_set_proxy(
-: 337: int keyval,
-: 338: MPID_Attr_copy_proxy copy_proxy,
-: 339: MPID_Attr_delete_proxy delete_proxy
-: 340: )
513: 341:{
-: 342: MPID_Keyval* keyval_ptr;
513: 343: MPID_Keyval_get_ptr( keyval, keyval_ptr );
513: 344: if(keyval_ptr == NULL)
|
#####: 345: return;
-: 346:
|
513: 347: keyval_ptr->copyfn.proxy = copy_proxy;
513: 348: keyval_ptr->delfn.proxy = delete_proxy;
-: 349:}
|