-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/pt2pt/greq_start.c
        -:    0:Graph:greq_start.gcno
        -:    0:Data:greq_start.gcda
        -:    0:Runs:910
        -:    0:Programs:295
        -:    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:
        -:    9:/* -- Begin Profiling Symbol Block for routine MPI_Grequest_start */
        -:   10:#if defined(HAVE_PRAGMA_WEAK)
        -:   11:#pragma weak MPI_Grequest_start = PMPI_Grequest_start
        -:   12:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
        -:   13:#pragma _HP_SECONDARY_DEF PMPI_Grequest_start  MPI_Grequest_start
        -:   14:#elif defined(HAVE_PRAGMA_CRI_DUP)
        -:   15:#pragma _CRI duplicate MPI_Grequest_start as PMPI_Grequest_start
        -:   16:#endif
        -:   17:/* -- End Profiling Symbol Block */
        -:   18:
        -:   19:PMPI_LOCAL int MPIR_Grequest_free_classes_on_finalize(void *extra_data);
        -:   20:
        -:   21:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
        -:   22:   the MPI routines.  You can use USE_WEAK_SYMBOLS to see if MPICH is
        -:   23:   using weak symbols to implement the MPI routines. */
        -:   24:#ifndef MPICH_MPI_FROM_PMPI
        -:   25:#undef MPI_Grequest_start
        -:   26:#define MPI_Grequest_start PMPI_Grequest_start
        -:   27:
        -:   28:/* preallocated grequest classes */
        -:   29:#ifndef MPID_GREQ_CLASS_PREALLOC
        -:   30:#define MPID_GREQ_CLASS_PREALLOC 2
        -:   31:#endif
        -:   32:
        -:   33:MPID_Grequest_class MPID_Grequest_class_direct[MPID_GREQ_CLASS_PREALLOC] = 
        -:   34:                                              { {0} };
        -:   35:MPIU_Object_alloc_t MPID_Grequest_class_mem = {0, 0, 0, 0, MPID_GREQ_CLASS,
        -:   36:	                                       sizeof(MPID_Grequest_class),
        -:   37:					       MPID_Grequest_class_direct,
        -:   38:					       MPID_GREQ_CLASS_PREALLOC, };
        -:   39:
        -:   40:/* We jump through some minor hoops to manage the list of classes ourselves and
        -:   41: * only register a single finalizer to avoid hitting limitations in the current
        -:   42: * finalizer code.  If the finalizer implementation is ever revisited this code
        -:   43: * is a good candidate for registering one callback per greq class and trimming
        -:   44: * some of this logic. */
        -:   45:int MPIR_Grequest_registered_finalizer = 0;
        -:   46:MPID_Grequest_class *MPIR_Grequest_class_list = NULL;
        -:   47:
        -:   48:/* Any internal routines can go here.  Make them static if possible.  If they
        -:   49:   are used by both the MPI and PMPI versions, use PMPI_LOCAL instead of 
        -:   50:   static; this macro expands into "static" if weak symbols are supported and
        -:   51:   into nothing otherwise. */
        -:   52:PMPI_LOCAL int MPIR_Grequest_free_classes_on_finalize(void *extra_data ATTRIBUTE((unused)))
       40:   53:{
       40:   54:    int mpi_errno = MPI_SUCCESS;
       40:   55:    MPID_Grequest_class *last = NULL;
       40:   56:    MPID_Grequest_class *cur = MPIR_Grequest_class_list;
        -:   57:
        -:   58:    /* FIXME MT this function is not thread safe when using fine-grained threading */
       40:   59:    MPIR_Grequest_class_list = NULL;
      120:   60:    while (cur) {
       40:   61:        last = cur;
       40:   62:        cur = last->next;
       40:   63:        MPIU_Handle_obj_free(&MPID_Grequest_class_mem, last);
        -:   64:    }
        -:   65:
       40:   66:    return mpi_errno;
        -:   67:}
        -:   68:
        -:   69:#else
        -:   70:extern MPID_Grequest_class MPID_Grequest_class_direct[];
        -:   71:extern MPIU_Object_alloc_t MPID_Grequest_class_mem;
        -:   72:extern int MPIR_Grequest_registered_finalizer;
        -:   73:extern MPID_Grequest_class *MPIR_Grequest_class_list;
        -:   74:#endif
        -:   75:
        -:   76:#undef FUNCNAME
        -:   77:#define FUNCNAME MPI_Grequest_start
        -:   78:
        -:   79:/*@
        -:   80:   MPI_Grequest_start - Create and return a user-defined request
        -:   81:
        -:   82:Input Parameters:
        -:   83:+ query_fn - callback function invoked when request status is queried (function)  
        -:   84:. free_fn - callback function invoked when request is freed (function) 
        -:   85:. cancel_fn - callback function invoked when request is cancelled (function) 
        -:   86:- extra_state - Extra state passed to the above functions.
        -:   87:
        -:   88:Output Parameter:
        -:   89:.  request - Generalized request (handle)
        -:   90:
        -:   91: Notes on the callback functions:
        -:   92: The return values from the callback functions must be a valid MPI error code
        -:   93: or class.  This value may either be the return value from any MPI routine
        -:   94: (with one exception noted below) or any of the MPI error classes. 
        -:   95: For portable programs, 'MPI_ERR_OTHER' may be used; to provide more 
        -:   96: specific information, create a new MPI error class or code with 
        -:   97: 'MPI_Add_error_class' or 'MPI_Add_error_code' and return that value.
        -:   98:
        -:   99: The MPI standard is not clear on the return values from the callback routines.
        -:  100: However, there are notes in the standard that imply that these are MPI error
        -:  101: codes.  For example, pages 169 line 46 through page 170, line 1 require that
        -:  102: the 'free_fn' return an MPI error code that may be used in the MPI completion
        -:  103: functions when they return 'MPI_ERR_IN_STATUS'.  
        -:  104:
        -:  105: The one special case is the error value returned by 'MPI_Comm_dup' when
        -:  106: the attribute callback routine returns a failure.  The MPI standard is not
        -:  107: clear on what values may be used to indicate an error return.  Further,
        -:  108: the Intel MPI test suite made use of non-zero values to indicate failure, 
        -:  109: and expected these values to be returned by the 'MPI_Comm_dup' when the 
        -:  110: attribute routines encountered an error.  Such error values may not be valid 
        -:  111: MPI error codes or classes.  Because of this, it is the user''s responsibility
        -:  112: to either use valid MPI error codes in return from the attribute callbacks,
        -:  113: if those error codes are to be returned by a generalized request callback,
        -:  114: or to detect and convert those error codes to valid MPI error codes (recall
        -:  115: that MPI error classes are valid error codes).  
        -:  116:
        -:  117:.N ThreadSafe
        -:  118:
        -:  119:.N Fortran
        -:  120:
        -:  121:.N Errors
        -:  122:.N MPI_SUCCESS
        -:  123:.N MPI_ERR_ARG
        -:  124:@*/
        -:  125:int MPI_Grequest_start( MPI_Grequest_query_function *query_fn, 
        -:  126:			MPI_Grequest_free_function *free_fn, 
        -:  127:			MPI_Grequest_cancel_function *cancel_fn, 
        -:  128:			void *extra_state, MPI_Request *request )
   644794:  129:{
        -:  130:    static const char FCNAME[] = "MPI_Grequest_start";
   644794:  131:    int mpi_errno = MPI_SUCCESS;
        -:  132:    MPID_Request *lrequest_ptr;
   644794:  133:    MPIU_THREADPRIV_DECL;
        -:  134:    MPID_MPI_STATE_DECL(MPID_STATE_MPI_GREQUEST_START);
        -:  135:
   644794:  136:    MPIR_ERRTEST_INITIALIZED_ORDIE();
        -:  137:    
   644794:  138:    MPIU_THREAD_CS_ENTER(ALLFUNC,);
        -:  139:    MPID_MPI_FUNC_ENTER(MPID_STATE_MPI_GREQUEST_START);
        -:  140:
        -:  141:    /* Validate parameters if error checking is enabled */
        -:  142:#   ifdef HAVE_ERROR_CHECKING
        -:  143:    {
        -:  144:        MPID_BEGIN_ERROR_CHECKS;
        -:  145:        {
   644794:  146:	    MPIR_ERRTEST_ARGNULL(request,"request",mpi_errno);
   644794:  147:            if (mpi_errno) goto fn_fail;
        -:  148:        }
        -:  149:        MPID_END_ERROR_CHECKS;
        -:  150:    }
        -:  151:#   endif /* HAVE_ERROR_CHECKING */
        -:  152:
        -:  153:    /* ... body of routine ...  */
        -:  154:    
   644794:  155:    lrequest_ptr = MPID_Request_create();
        -:  156:    /* --BEGIN ERROR HANDLING-- */
   644794:  157:    if (lrequest_ptr == NULL)
        -:  158:    {
    #####:  159:	mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE, 
        -:  160:					  FCNAME, __LINE__, MPI_ERR_OTHER, 
        -:  161:					  "**nomem", "**nomem %s", 
        -:  162:					  "generalized request" );
    #####:  163:	goto fn_fail;
        -:  164:    }
        -:  165:    /* --END ERROR HANDLING-- */
        -:  166:    
   644794:  167:    lrequest_ptr->kind                 = MPID_UREQUEST;
   644794:  168:    MPIU_Object_set_ref( lrequest_ptr, 1 );
   644794:  169:    lrequest_ptr->cc_ptr               = &lrequest_ptr->cc;
   644794:  170:    lrequest_ptr->cc                   = 1;
   644794:  171:    lrequest_ptr->comm                 = NULL;
   644794:  172:    lrequest_ptr->cancel_fn            = cancel_fn;
   644794:  173:    lrequest_ptr->free_fn              = free_fn;
   644794:  174:    lrequest_ptr->query_fn             = query_fn;
   644794:  175:    lrequest_ptr->poll_fn              = NULL;
   644794:  176:    lrequest_ptr->wait_fn              = NULL;
   644794:  177:    lrequest_ptr->grequest_extra_state = extra_state;
   644794:  178:    lrequest_ptr->greq_lang            = MPID_LANG_C;
   644794:  179:    *request = lrequest_ptr->handle;
        -:  180:    
        -:  181:    /* ... end of body of routine ... */
        -:  182:
   644794:  183:  fn_exit:
        -:  184:    MPID_MPI_FUNC_EXIT(MPID_STATE_MPI_GREQUEST_START);
   644794:  185:    MPIU_THREAD_CS_EXIT(ALLFUNC,);
   644794:  186:    return mpi_errno;
        -:  187:    
    #####:  188:  fn_fail:
        -:  189:    /* --BEGIN ERROR HANDLING-- */
        -:  190:#   ifdef HAVE_ERROR_CHECKING
        -:  191:    {
    #####:  192:	mpi_errno = MPIR_Err_create_code(
        -:  193:	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, 
        -:  194:	    "**mpi_grequest_start",
        -:  195:	    "**mpi_grequest_start %p %p %p %p %p", 
        -:  196:	    query_fn, free_fn, cancel_fn, extra_state, request);
        -:  197:    }
        -:  198:#   endif
    #####:  199:    mpi_errno = MPIR_Err_return_comm( NULL, FCNAME, mpi_errno );
    #####:  200:    goto fn_exit;
        -:  201:    /* --END ERROR HANDLING-- */
        -:  202:}
        -:  203:
        -:  204:/* -- Begin Profiling Symbol Block for routine MPIX_Grequest_class_create*/
        -:  205:#if defined(HAVE_PRAGMA_WEAK)
        -:  206:#pragma weak MPIX_Grequest_class_create = PMPIX_Grequest_class_create
        -:  207:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
        -:  208:#pragma _HP_SECONDARY_DEF PMPIX_Grequest_class_create MPIX_Grequest_class_create
        -:  209:#elif defined(HAVE_PRAGMA_CRI_DUP)
        -:  210:#pragma _CRI duplicate MPIX_Grequest_class_create as PMPIX_Grequest_class_create
        -:  211:#endif
        -:  212:/* -- End Profiling Symbol Block */
        -:  213:
        -:  214:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
        -:  215:   the MPI routines */
        -:  216:#ifndef MPICH_MPI_FROM_PMPI
        -:  217:#undef MPIX_Grequest_class_create
        -:  218:#define MPIX_Grequest_class_create PMPIX_Grequest_class_create
        -:  219:#endif
        -:  220:
        -:  221:#undef FUNCNAME
        -:  222:#define FUNCNAME MPIX_Grequest_class_create
        -:  223:/* extensions for Generalized Request redesign paper */
        -:  224:int MPIX_Grequest_class_create(MPI_Grequest_query_function *query_fn,
        -:  225:		               MPI_Grequest_free_function *free_fn,
        -:  226:			       MPI_Grequest_cancel_function *cancel_fn,
        -:  227:			       MPIX_Grequest_poll_function *poll_fn,
        -:  228:			       MPIX_Grequest_wait_function *wait_fn,
        -:  229:			       MPIX_Grequest_class *greq_class)
       40:  230:{
        -:  231:    	static const char FCNAME[] = "MPIX_Grequest_class_create";
        -:  232:	MPID_Grequest_class *class_ptr;
       40:  233:	int mpi_errno = MPI_SUCCESS;
        -:  234:
       40:  235:	class_ptr = (MPID_Grequest_class *) 
        -:  236:		MPIU_Handle_obj_alloc(&MPID_Grequest_class_mem);
        -:  237:        /* --BEGIN ERROR HANDLING-- */
       40:  238:	if (!class_ptr)
        -:  239:	{
    #####:  240:	    mpi_errno = MPIR_Err_create_code (MPI_SUCCESS, 
        -:  241:			    MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, 
        -:  242:			    MPI_ERR_OTHER, "**nomem", 
        -:  243:			    "**nomem %s", "MPIX_Grequest_class");
    #####:  244:	    goto fn_fail;
        -:  245:	} 
        -:  246:	/* --END ERROR HANDLING-- */
        -:  247:
       40:  248:	*greq_class = class_ptr->handle;
       40:  249:	class_ptr->query_fn = query_fn;
       40:  250:	class_ptr->free_fn = free_fn;
       40:  251:	class_ptr->cancel_fn = cancel_fn;
       40:  252:	class_ptr->poll_fn = poll_fn;
       40:  253:	class_ptr->wait_fn = wait_fn;
        -:  254:
       40:  255:	MPIU_Object_set_ref(class_ptr, 1);
        -:  256:
       40:  257:        if (MPIR_Grequest_class_list == NULL) {
       40:  258:            class_ptr->next = NULL;
        -:  259:        }
        -:  260:        else {
    #####:  261:            class_ptr->next = MPIR_Grequest_class_list;
        -:  262:        }
       40:  263:        MPIR_Grequest_class_list = class_ptr;
       40:  264:        if (!MPIR_Grequest_registered_finalizer) {
        -:  265:            /* must run before (w/ higher priority than) the handle check
        -:  266:             * finalizer in order avoid being flagged as a leak */
       40:  267:            MPIR_Add_finalize(&MPIR_Grequest_free_classes_on_finalize,
        -:  268:                              NULL,
        -:  269:                              MPIR_FINALIZE_CALLBACK_HANDLE_CHECK_PRIO+1);
       40:  270:            MPIR_Grequest_registered_finalizer = 1;
        -:  271:        }
        -:  272:
        -:  273:	/* ... end of body of routine ... */
       40:  274:fn_exit:
       40:  275:	return mpi_errno;
    #####:  276:fn_fail:
        -:  277:    /* --BEGIN ERROR HANDLING-- */
        -:  278:#   ifdef HAVE_ERROR_CHECKING
        -:  279:    {
    #####:  280:	mpi_errno = MPIR_Err_create_code(
        -:  281:	    mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, 
        -:  282:	    "**mpix_grequest_class_create",
        -:  283:	    "**mpix_grequest_class_create %p %p %p %p %p", 
        -:  284:	    query_fn, free_fn, cancel_fn, poll_fn, wait_fn);
        -:  285:    }
        -:  286:#   endif
    #####:  287:    mpi_errno = MPIR_Err_return_comm( 0, FCNAME, mpi_errno );
    #####:  288:    goto fn_exit;
        -:  289:    /* --END ERROR HANDLING-- */
        -:  290:}
        -:  291:
        -:  292:/* -- Begin Profiling Symbol Block for routine MPIX_Grequest_class_allocate */
        -:  293:#if defined(HAVE_PRAGMA_WEAK)
        -:  294:#pragma weak MPIX_Grequest_class_allocate = PMPIX_Grequest_class_allocate
        -:  295:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
        -:  296:#pragma _HP_SECONDARY_DEF PMPI_Grequest_class_allocate MPIX_Grequest_class_allocate
        -:  297:#elif defined(HAVE_PRAGMA_CRI_DUP)
        -:  298:#pragma _CRI duplicate MPIX_Grequest_class_allocate as PMPIX_Grequest_class_allocate
        -:  299:#endif
        -:  300:/* -- End Profiling Symbol Block */
        -:  301:
        -:  302:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
        -:  303:   the MPI routines */
        -:  304:#ifndef MPICH_MPI_FROM_PMPI
        -:  305:#undef MPIX_Grequest_class_allocate
        -:  306:#define MPIX_Grequest_class_allocate PMPIX_Grequest_class_allocate
        -:  307:#endif
        -:  308:
        -:  309:#undef FUNCNAME
        -:  310:#define FUNCNAME MPIX_Grequest_class_allocate
        -:  311:
        -:  312:int MPIX_Grequest_class_allocate(MPIX_Grequest_class greq_class, 
        -:  313:		                void *extra_state, 
        -:  314:				MPI_Request *request)
   532368:  315:{
        -:  316:	int mpi_errno;
        -:  317:	MPID_Request *lrequest_ptr;
        -:  318:	MPID_Grequest_class *class_ptr;
        -:  319:
        -:  320:
   532368:  321:	MPID_Grequest_class_get_ptr(greq_class, class_ptr);
   532368:  322:	mpi_errno = MPI_Grequest_start(class_ptr->query_fn, 
        -:  323:			class_ptr->free_fn, class_ptr->cancel_fn, 
        -:  324:			extra_state, request);
   532368:  325:	if (mpi_errno == MPI_SUCCESS)
        -:  326:	{
   532368:  327:		MPID_Request_get_ptr(*request, lrequest_ptr);
   532368:  328:		lrequest_ptr->poll_fn     = class_ptr->poll_fn;
   532368:  329:		lrequest_ptr->wait_fn     = class_ptr->wait_fn;
   532368:  330:		lrequest_ptr->greq_class  = greq_class;  
        -:  331:	}
   532368:  332:	return mpi_errno;
        -:  333:}
        -:  334:
        -:  335:/* -- Begin Profiling Symbol Block for routine MPIX_Grequest_start */
        -:  336:#if defined(HAVE_PRAGMA_WEAK)
        -:  337:#pragma weak MPIX_Grequest_start = PMPIX_Grequest_start
        -:  338:#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
        -:  339:#pragma _HP_SECONDARY_DEF PMPI_Grequest_start MPIX_Grequest_start
        -:  340:#elif defined(HAVE_PRAGMA_CRI_DUP)
        -:  341:#pragma _CRI duplicate MPIX_Grequest_start as PMPIX_Grequest_start
        -:  342:#endif
        -:  343:/* -- End Profiling Symbol Block */
        -:  344:
        -:  345:/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
        -:  346:   the MPI routines */
        -:  347:#ifndef MPICH_MPI_FROM_PMPI
        -:  348:#undef MPIX_Grequest_start
        -:  349:#define MPIX_Grequest_start PMPIX_Grequest_start
        -:  350:#endif
        -:  351:
        -:  352:#undef FUNCNAME
        -:  353:#define FUNCNAME MPIX_Grequest_start
        -:  354:
        -:  355:int MPIX_Grequest_start( MPI_Grequest_query_function *query_fn, 
        -:  356:			MPI_Grequest_free_function *free_fn, 
        -:  357:			MPI_Grequest_cancel_function *cancel_fn, 
        -:  358:			MPIX_Grequest_poll_function *poll_fn,
        -:  359:			MPIX_Grequest_wait_function *wait_fn,
        -:  360:			void *extra_state, MPI_Request *request )
    #####:  361:{
        -:  362:    int mpi_errno;
        -:  363:    MPID_Request *lrequest_ptr;
        -:  364:
    #####:  365:    mpi_errno = MPI_Grequest_start(query_fn, free_fn, cancel_fn, 
        -:  366:		    extra_state, request);
        -:  367:
    #####:  368:    if (mpi_errno == MPI_SUCCESS)
        -:  369:    { 
    #####:  370:	MPID_Request_get_ptr(*request, lrequest_ptr);
    #####:  371:        lrequest_ptr->poll_fn              = poll_fn;
    #####:  372:	lrequest_ptr->wait_fn              = wait_fn;
        -:  373:    }
        -:  374:
    #####:  375:    return mpi_errno;
        -:  376:}