-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/src/mpid_port.c
        -:    0:Graph:mpid_port.gcno
        -:    0:Data:mpid_port.gcda
        -:    0:Runs:3459
        -:    0:Programs:899
        -:    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 "mpidimpl.h"
        -:    8:
        -:    9:static int setupPortFunctions = 1;
        -:   10:
        -:   11:#ifndef MPIDI_CH3_HAS_NO_DYNAMIC_PROCESS
        -:   12:static int MPIDI_Open_port(MPID_Info *, char *);
        -:   13:static int MPIDI_Close_port(const char *);
        -:   14:
        -:   15:/* Define the functions that are used to implement the port
        -:   16: * operations */
        -:   17:static MPIDI_PortFns portFns = { MPIDI_Open_port,
        -:   18:				 MPIDI_Close_port,
        -:   19:				 MPIDI_Comm_accept,
        -:   20:				 MPIDI_Comm_connect };
        -:   21:#else
        -:   22:static MPIDI_PortFns portFns = { 0, 0, 0, 0 };
        -:   23:#endif
        -:   24:
        -:   25:/*@
        -:   26:   MPID_Open_port - Open an MPI Port
        -:   27:
        -:   28:   Input Arguments:
        -:   29:.  MPI_Info info - info
        -:   30:
        -:   31:   Output Arguments:
        -:   32:.  char *port_name - port name
        -:   33:
        -:   34:   Notes:
        -:   35:
        -:   36:.N Errors
        -:   37:.N MPI_SUCCESS
        -:   38:.N MPI_ERR_OTHER
        -:   39:@*/
        -:   40:#undef FUNCNAME
        -:   41:#define FUNCNAME MPID_Open_port
        -:   42:#undef FCNAME
        -:   43:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   44:int MPID_Open_port(MPID_Info *info_ptr, char *port_name)
      372:   45:{
      372:   46:    int mpi_errno=MPI_SUCCESS;
        -:   47:    MPIDI_STATE_DECL(MPID_STATE_MPID_OPEN_PORT);
        -:   48:
        -:   49:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_OPEN_PORT);
        -:   50:
        -:   51:    /* Check to see if we need to setup channel-specific functions
        -:   52:       for handling the port operations */
      372:   53:    if (setupPortFunctions) {
       36:   54:	MPIU_CALL(MPIDI_CH3,PortFnsInit( &portFns ));
       36:   55:	setupPortFunctions = 0;
        -:   56:    }
        -:   57:
        -:   58:    /* The default for this function is MPIDI_Open_port.
        -:   59:       A channel may define its own function and set it in the 
        -:   60:       init check above; such a function may be named MPIDI_CH3_Open_port.
        -:   61:       In addition, not all channels can implement this operation, so
        -:   62:       those channels will set the function pointer to NULL */
      372:   63:    if (portFns.OpenPort) {
      372:   64:	mpi_errno = portFns.OpenPort( info_ptr, port_name );
      372:   65:	if (mpi_errno != MPI_SUCCESS) {
    #####:   66:	    MPIU_ERR_POP(mpi_errno);
        -:   67:	}
        -:   68:    }
        -:   69:    else {
    #####:   70:	MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**notimpl" );
        -:   71:    }
        -:   72:
      372:   73: fn_fail:
        -:   74:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_OPEN_PORT);
      372:   75:    return mpi_errno;
        -:   76:}
        -:   77:
        -:   78:/*@
        -:   79:   MPID_Close_port - Close port
        -:   80:
        -:   81:   Input Parameter:
        -:   82:.  port_name - Name of MPI port to close
        -:   83:
        -:   84:   Notes:
        -:   85:
        -:   86:.N Errors
        -:   87:.N MPI_SUCCESS
        -:   88:.N MPI_ERR_OTHER
        -:   89:
        -:   90:@*/
        -:   91:#undef FUNCNAME
        -:   92:#define FUNCNAME MPID_Close_port
        -:   93:#undef FCNAME
        -:   94:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   95:int MPID_Close_port(const char *port_name)
      370:   96:{
      370:   97:    int mpi_errno=MPI_SUCCESS;
        -:   98:    MPIDI_STATE_DECL(MPID_STATE_MPID_CLOSE_PORT);
        -:   99:
        -:  100:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_CLOSE_PORT);
        -:  101:
        -:  102:    /* Check to see if we need to setup channel-specific functions
        -:  103:       for handling the port operations */
      370:  104:    if (setupPortFunctions) {
    #####:  105:	MPIU_CALL(MPIDI_CH3,PortFnsInit( &portFns ));
    #####:  106:	setupPortFunctions = 0;
        -:  107:    }
        -:  108:
        -:  109:    /* The default for this function is 0 (no function).
        -:  110:       A channel may define its own function and set it in the 
        -:  111:       init check above; such a function may be named MPIDI_CH3_Close_port */
      370:  112:    if (portFns.ClosePort) {
      370:  113:	mpi_errno = portFns.ClosePort( port_name );
      370:  114:	if (mpi_errno != MPI_SUCCESS) {
    #####:  115:	    MPIU_ERR_POP(mpi_errno);
        -:  116:	}
        -:  117:    }
        -:  118:    else {
    #####:  119:	MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**notimpl" );
        -:  120:    }
        -:  121:
      370:  122: fn_fail:	
        -:  123:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_CLOSE_PORT);
      370:  124:    return mpi_errno;
        -:  125:}
        -:  126:
        -:  127:#undef FUNCNAME
        -:  128:#define FUNCNAME MPID_Comm_accept
        -:  129:#undef FCNAME
        -:  130:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  131:int MPID_Comm_accept(char * port_name, MPID_Info * info, int root, 
        -:  132:		     MPID_Comm * comm, MPID_Comm ** newcomm_ptr)
     1386:  133:{
     1386:  134:    int mpi_errno = MPI_SUCCESS;
        -:  135:    MPIDI_STATE_DECL(MPID_STATE_MPID_COMM_ACCEPT);
        -:  136:
        -:  137:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_COMM_ACCEPT);
        -:  138:
        -:  139:    /* Check to see if we need to setup channel-specific functions
        -:  140:       for handling the port operations */
     1386:  141:    if (setupPortFunctions) {
       16:  142:	MPIU_CALL(MPIDI_CH3,PortFnsInit( &portFns ));
       16:  143:	setupPortFunctions = 0;
        -:  144:    }
        -:  145:
        -:  146:    /* A channel may define its own function and set it in the 
        -:  147:       init check above; such a function may be named MPIDI_CH3_Comm_accept.
        -:  148:       If the function is null, we signal a not-implemented error */
     1386:  149:    if (portFns.CommAccept) {
     1386:  150:	mpi_errno = portFns.CommAccept( port_name, info, root, comm, 
        -:  151:					newcomm_ptr );
     1386:  152:	if (mpi_errno != MPI_SUCCESS) {
    #####:  153:	    MPIU_ERR_POP(mpi_errno);
        -:  154:	}
        -:  155:    }
        -:  156:    else {
    #####:  157:	MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**notimpl" );
        -:  158:    }
        -:  159:
     1386:  160: fn_fail:
        -:  161:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_COMM_ACCEPT);
     1386:  162:    return mpi_errno;
        -:  163:}
        -:  164:
        -:  165:#undef FUNCNAME
        -:  166:#define FUNCNAME MPID_Comm_connect
        -:  167:#undef FCNAME
        -:  168:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  169:int MPID_Comm_connect(const char * port_name, MPID_Info * info, int root, 
        -:  170:		      MPID_Comm * comm, MPID_Comm ** newcomm_ptr)
     1318:  171:{
     1318:  172:    int mpi_errno=MPI_SUCCESS;
        -:  173:    MPIDI_STATE_DECL(MPID_STATE_MPID_COMM_CONNECT);
        -:  174:
        -:  175:    MPIDI_FUNC_ENTER(MPID_STATE_MPID_COMM_CONNECT);
        -:  176:
        -:  177:    /* Check to see if we need to setup channel-specific functions
        -:  178:       for handling the port operations */
     1318:  179:    if (setupPortFunctions) {
      415:  180:	MPIU_CALL(MPIDI_CH3,PortFnsInit( &portFns ));
      415:  181:	setupPortFunctions = 0;
        -:  182:    }
        -:  183:
        -:  184:    /* A channel may define its own function and set it in the 
        -:  185:       init check above; such a function may be named MPIDI_CH3_Comm_connect.
        -:  186:       If the function is null, we signal a not-implemented error */
     1318:  187:    if (portFns.CommConnect) {
     1318:  188:	mpi_errno = portFns.CommConnect( port_name, info, root, comm, 
        -:  189:					 newcomm_ptr );
     1318:  190:	if (mpi_errno != MPI_SUCCESS) {
        1:  191:	    MPIU_ERR_POP(mpi_errno);
        -:  192:	}
        -:  193:    }
        -:  194:    else {
    #####:  195:	MPIU_ERR_SET(mpi_errno, MPI_ERR_OTHER, "**notimpl" );
        -:  196:    }
        -:  197:
     1318:  198: fn_fail:
        -:  199:    MPIDI_FUNC_EXIT(MPID_STATE_MPID_COMM_CONNECT);
     1318:  200:    return mpi_errno;
        -:  201:}
        -:  202:
        -:  203:/* ------------------------------------------------------------------------- */
        -:  204:#ifndef MPIDI_CH3_HAS_NO_DYNAMIC_PROCESS
        -:  205:
        -:  206:/*
        -:  207: * Here are the routines that provide some of the default implementations
        -:  208: * for the Port routines.
        -:  209: *
        -:  210: * MPIDI_Open_port - creates a port "name" that includes a tag value that
        -:  211: * is used to separate different MPI Port values.  That tag value is
        -:  212: * extracted with MPIDI_GetTagFromPort
        -:  213: * MPIDI_GetTagFromPort - Routine to return the tag associated with a port.
        -:  214: *
        -:  215: * The port_name_tag is used in the connect and accept messages that 
        -:  216: * are used in the connect/accept protocol that is implemented in the
        -:  217: * ch3u_port.c file.
        -:  218: */
        -:  219:
        -:  220:#define MPIDI_CH3I_PORT_NAME_TAG_KEY "tag"
        -:  221:
        -:  222:/* Though the port_name_tag_mask itself is an int, we can only have as
        -:  223: * many tags as the context_id space can support. */
        -:  224:static int port_name_tag_mask[MPIR_MAX_CONTEXT_MASK] = { 0 };
        -:  225:
        -:  226:static int get_port_name_tag(int * port_name_tag)
      372:  227:{
        -:  228:    int i, j;
      372:  229:    int mpi_errno = MPI_SUCCESS;
        -:  230:
      372:  231:    for (i = 0; i < MPIR_MAX_CONTEXT_MASK; i++)
      372:  232:	if (port_name_tag_mask[i] != ~0)
      372:  233:	    break;
        -:  234:
      372:  235:    if (i < MPIR_MAX_CONTEXT_MASK) {
        -:  236:	/* Found a free tag. port_name_tag_mask[i] is not fully used
        -:  237:	 * up. */
        -:  238:
        -:  239:	/* OR the mask value with powers of two. If the OR value is
        -:  240:	 * the same as the original value, then it means that the
        -:  241:	 * OR'ed bit was originally 1 (used); otherwise, it was
        -:  242:	 * originally 0 (free). */
      442:  243:	for (j = 0; j < (8 * sizeof(int)); j++) {
      442:  244:	    if ((port_name_tag_mask[i] | (1 << ((8 * sizeof(int)) - j - 1))) !=
        -:  245:		port_name_tag_mask[i]) {
        -:  246:		/* Mark the appropriate bit as used and return that */
      372:  247:		port_name_tag_mask[i] |= (1 << ((8 * sizeof(int)) - j - 1));
      372:  248:		*port_name_tag = ((i * 8 * sizeof(int)) + j);
      372:  249:		goto fn_exit;
        -:  250:	    }
        -:  251:	}
        -:  252:    }
        -:  253:    else {
    #####:  254:	goto fn_fail;
        -:  255:    }
        -:  256:
      372:  257:fn_exit:
      372:  258:    return mpi_errno;
        -:  259:
    #####:  260:fn_fail:
        -:  261:    /* Everything is used up */
    #####:  262:    *port_name_tag = -1;
    #####:  263:    mpi_errno = MPI_ERR_OTHER;
    #####:  264:    goto fn_exit;
        -:  265:}
        -:  266:
        -:  267:static void free_port_name_tag(int tag)
      370:  268:{
        -:  269:    int index, rem_tag;
        -:  270:
      370:  271:    index = tag / (sizeof(int) * 8);
      370:  272:    rem_tag = tag - (index * sizeof(int) * 8);
        -:  273:
      370:  274:    port_name_tag_mask[index] &= ~(1 << ((8 * sizeof(int)) - 1 - rem_tag));
      370:  275:}
        -:  276:
        -:  277:/*
        -:  278: * MPIDI_Open_port()
        -:  279: */
        -:  280:#undef FUNCNAME
        -:  281:#define FUNCNAME MPIDI_Open_port
        -:  282:#undef FCNAME
        -:  283:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  284:static int MPIDI_Open_port(MPID_Info *info_ptr, char *port_name)
      372:  285:{
      372:  286:    int mpi_errno = MPI_SUCCESS;
        -:  287:    int len;
      372:  288:    int port_name_tag = 0; /* this tag is added to the business card,
        -:  289:                              which is then returned as the port name */
      372:  290:    int myRank = MPIR_Process.comm_world->rank;
        -:  291:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_OPEN_PORT);
        -:  292:
        -:  293:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_OPEN_PORT);
        -:  294:
      372:  295:    mpi_errno = get_port_name_tag(&port_name_tag);
      372:  296:    MPIU_ERR_CHKANDJUMP(mpi_errno,mpi_errno,MPI_ERR_OTHER,"**argstr_port_name_tag");
        -:  297:
      372:  298:    len = MPI_MAX_PORT_NAME;
      372:  299:    mpi_errno = MPIU_Str_add_int_arg(&port_name, &len, 
        -:  300:			MPIDI_CH3I_PORT_NAME_TAG_KEY, port_name_tag);
        -:  301:
        -:  302:    /* FIXME: MPIU_xxx routines should return regular mpi error codes */
      372:  303:    if (mpi_errno != MPIU_STR_SUCCESS) {
    #####:  304:	mpi_errno = MPI_SUCCESS;
    #####:  305:	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**argstr_port_name_tag");
        -:  306:    }
        -:  307:
        -:  308:    /* This works because Get_business_card uses the same MPIU_Str_xxx 
        -:  309:       functions as above to add the business card to the input string */
        -:  310:    /* FIXME: We should instead ask the mpid_pg routines to give us
        -:  311:       a connection string. There may need to be a separate step to 
        -:  312:       restrict us to a connection information that is only valid for
        -:  313:       connections between processes that are started separately (e.g.,
        -:  314:       may not use shared memory).  We may need a channel-specific 
        -:  315:       function to create an exportable connection string.  */
      372:  316:    mpi_errno = MPIU_CALL(MPIDI_CH3,Get_business_card(myRank, port_name, len));
        -:  317:    MPIU_DBG_MSG_FMT(CH3, VERBOSE, (MPIU_DBG_FDEST, "port_name = %s", port_name));
        -:  318:
      372:  319:fn_exit:
        -:  320:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_OPEN_PORT);
      372:  321:    return mpi_errno;
        -:  322:fn_fail:
        -:  323:    goto fn_exit;
        -:  324:}
        -:  325:
        -:  326:/*
        -:  327: * MPIDI_Close_port()
        -:  328: */
        -:  329:#undef FUNCNAME
        -:  330:#define FUNCNAME MPIDI_Close_port
        -:  331:#undef FCNAME
        -:  332:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  333:static int MPIDI_Close_port(const char *port_name)
      370:  334:{
      370:  335:    int mpi_errno = MPI_SUCCESS;
        -:  336:    int port_name_tag;
        -:  337:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CLOSE_PORT);
        -:  338:
        -:  339:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CLOSE_PORT);
        -:  340:
      370:  341:    mpi_errno = MPIDI_GetTagFromPort(port_name, &port_name_tag);
      370:  342:    MPIU_ERR_CHKANDJUMP(mpi_errno, mpi_errno, MPI_ERR_OTHER,"**argstr_port_name_tag");
        -:  343:
      370:  344:    free_port_name_tag(port_name_tag);
        -:  345:
      370:  346:fn_exit:
        -:  347:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CLOSE_PORT);
      370:  348:    return mpi_errno;
        -:  349:fn_fail:
        -:  350:    goto fn_exit;
        -:  351:}
        -:  352:
        -:  353:/*
        -:  354: * The connect and accept routines use this routine to get the port tag
        -:  355: * from the port name.
        -:  356: */
        -:  357:int MPIDI_GetTagFromPort( const char *port_name, int *port_name_tag )
     2374:  358:{
        -:  359:    int mpi_errno;
        -:  360:
     2374:  361:    mpi_errno = MPIU_Str_get_int_arg(port_name, MPIDI_CH3I_PORT_NAME_TAG_KEY,
        -:  362:                                     port_name_tag);
     2374:  363:    if (mpi_errno != MPIU_STR_SUCCESS)
        -:  364:    {
    #####:  365:	mpi_errno = MPI_SUCCESS;
    #####:  366:	MPIU_ERR_SET(mpi_errno,MPI_ERR_OTHER, "**argstr_no_port_name_tag");
        -:  367:    }
     2374:  368:    return mpi_errno;
        -:  369:}
        -:  370:
        -:  371:#endif