⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p4_utils.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- */#include "p4.h"#include "p4_sys.h"static char hold_patchlevel[16];static char hold_machine_type[16];/* getenv is part of stdlib.h */#ifndef HAVE_STDLIB_Hextern char *getenv();#endif#ifdef SCYLD_BEOWULFstatic void beowulf_init(void);#endifvoid p4_post_init( void ){    /* This routine can be called to do any further initialization after p4       has itself been intialized. */#ifdef P4_PRECONNECT    /* set up all sockets on systems with interrupt-unsafe socket calls */    p4_dprintfl(10, "pre-establishing connections\n");    p4_establish_all_conns();#endif}    char *p4_version( void ){    strcpy(hold_patchlevel,P4_PATCHLEVEL);    return(hold_patchlevel);}char *p4_machine_type( void ){    strcpy(hold_machine_type,P4_MACHINE_TYPE);    return(hold_machine_type);}int p4_initenv(int *argc, char **argv){    int i, rc;    char *env_value;    int p4_globmemsize;    P4BOOL am_slave = P4_FALSE;    /*****    char hname[100];    int hlen = 100;    gethostname(hname,hlen);    printf("entering p4_initenv on %s\n",hname);    *****/    sprintf(whoami_p4, "xm_%d", (int)getpid());    p4_globmemsize = GLOBMEMSIZE;		/* 7/12/95, bri@sgi.com */    env_value = getenv("P4_GLOBMEMSIZE");	/* 7/12/95, bri@sgi.com */    if (env_value)				/* 7/12/95, bri@sgi.com */	    p4_globmemsize = atoi(env_value);	/* 7/12/95, bri@sgi.com */    globmemsize = p4_globmemsize;		/* 7/12/95, bri@sgi.com */    logging_flag = P4_FALSE;    /* Set no default port */    /* sserver_port = 753; */    sserver_port = -1;    process_args(argc,argv);    for (i=0; i < *argc; i++)    {	if ((strcmp(argv[i], "-p4amslave") == 0) ||	    (strcmp(argv[i], "-amp4slave") == 0) ||            (strcmp(argv[i], "-p4amp4slave") == 0))	{	    strcpy(argv[i]," ");    	    /* strip this arg as Prolog engine flags begin with - SRM */	    am_slave = P4_TRUE;	}    }    p4_dprintfl(90,"mport=%d nodenum=%d\n",execer_mastport,execer_mynodenum);    if (execer_mastport  &&  execer_mynodenum)        am_slave = P4_TRUE;#   if defined(SP1_EUI)    mpc_environ(&eui_numtasks,&eui_mynode);#   endif#   if defined(SP1_EUIH)    mp_environ(&euih_numtasks,&euih_mynode);#   endif#   if defined(MEIKO_CS2)    mpsc_init();#   endif#   if defined(SCYLD_BEOWULF)    beowulf_init();#   endif#   if defined(IPSC860) || defined(CM5)     || defined(NCUBE)  \                        || defined(SP1_EUI) || defined(SP1_EUIH)    if (MYNODE() != 0)        am_slave = P4_TRUE;#    endif#   if defined(CM5)    CMMD_fset_io_mode( stdin,  CMMD_independent );    CMMD_fset_io_mode( stdout, CMMD_independent );    CMMD_fset_io_mode( stderr, CMMD_independent );#   endif    p4_local  = NULL;    p4_global = NULL;    if (am_slave)    {#       if defined(IPSC860)  ||  defined(CM5)     ||  defined(NCUBE) \	                     ||  defined(SP1_EUI) || defined(SP1_EUIH)        if (MYNODE() == 0)	{#           if defined(IPSC860_SOCKETS)  ||  defined(CM5_SOCKETS)  ||  defined(NCUBE_SOCKETS)	    rc = rm_start(argc, argv);#           endif	}	else	{	    rc = ns_start(argc, argv);	}#       else	rc = rm_start(argc, argv);#       endif	ALOG_SETUP(p4_local->my_id,ALOG_TRUNCATE);    }    else    {        /* Master */	rc = bm_start(argc, argv);        ALOG_MASTER(0,ALOG_TRUNCATE);        ALOG_DEFINE(BEGIN_USER,"beg_user","");        ALOG_DEFINE(END_USER,"end_user","");        ALOG_DEFINE(BEGIN_SEND,"beg_send","");        ALOG_DEFINE(END_SEND,"end_send","");        ALOG_DEFINE(BEGIN_RECV,"beg_recv","");        ALOG_DEFINE(END_RECV,"end_recv","");        ALOG_DEFINE(BEGIN_WAIT,"beg_wait","");        ALOG_DEFINE(END_WAIT,"end_wait","");    }    ALOG_LOG(p4_local->my_id,BEGIN_USER,0,"");    return (rc);}char *p4_shmalloc( int n ){    char *rc;    if ((rc = MD_shmalloc(n)) == NULL)	p4_dprintf("p4_shmalloc returning NULL; request = %d bytes\n\You can increase the amount of memory by setting the environment variable\n\P4_GLOBMEMSIZE (in bytes); the current size is %d\n",n, globmemsize);    return (rc);}P4VOID p4_shfree( P4VOID *p ){    MD_shfree(p);}int p4_num_cluster_ids( void ){    return (p4_global->local_slave_count + 1);}int p4_num_total_ids( void ){    return (p4_global->num_in_proctable);}int p4_num_total_slaves( void ){    return (p4_global->num_in_proctable - 1);}P4VOID p4_global_barrier( int type ){    int dummy[1];    dummy[0] = 0;    p4_global_op(type, (char *) dummy, 1, sizeof(int), p4_int_sum_op, P4INT);}P4VOID p4_get_cluster_masters( int *numids, int ids[] ){    int node;    ids[0] = 0;    *numids = 1;    for (node = 1; node < p4_global->num_in_proctable; node++)    {	if (p4_global->proctable[node].slave_idx != 0)	    continue;	ids[(*numids)++] = node;    }}P4VOID p4_get_cluster_ids( int *start, int *end ){    *start = p4_global->low_cluster_id;    *end = p4_global->hi_cluster_id;}/* This is used to figure out the local id of the calling process by * indexing into the proctable until you find a hostname and a unix id * that are the same as yours. */int p4_get_my_id_from_proc( void ){    int i, my_unix_id;    int n_match, match_id, best_match_id, best_match_nchars;    struct proc_info *pi;    struct hostent *pghp;    struct hostent myh;		    struct in_addr myaddr;       /* 8/14/96, llewins@msmail4.hac.com */    char myname[MAXHOSTNAMELEN]; /* 9/10/96, llewins@msmail4.hac.com */#   if (defined(IPSC860)  &&  !defined(IPSC860_SOCKETS))  ||  \       (defined(CM5)      &&  !defined(CM5_SOCKETS))      ||  \       (defined(NCUBE)    &&  !defined(NCUBE_SOCKETS))    ||  \       (defined(SP1_EUI))                                 ||  \       (defined(SP1_EUIH))    return(MYNODE());#   else    my_unix_id = getpid();    if (p4_local->my_id == LISTENER_ID)	return (LISTENER_ID);/*    p4_dprintf( "proctable size is %d\n", p4_global->num_in_proctable ); */    /*     * The following code identifies the rank of the running process relative     * to the procgroup file.  It does this by finding the pid of the process     * in the proctable, and comparing it to the procid of the calling process.     * A match isn't good enough, since some clusters could manage to      * co-incidentally assign the same process id to several of the processes     * in the procgroup.  To check for this case, we compare the host name     * in the procgroup to the hostname of the calling process.     *     * BUT what we really want to compare is an id of the physical hardware,     * and since a machine might have multiple network interfaces, this test     * might also fail.  So as a backstop, if there is precisely ONE match     * to the process ids, we accept that as the UNIQUE solution.     *      * Note that this code is trying to catch a procgroup file that is      * inconsistent with the build.  This should be caught in the procgroup     * file reading routine instead.     *     * Remaining bugs: if there are multiple matches, we can't resolve which     * we are if the hostname matching didn't find us (because of different     * interfaces).     *     * To fix the test for a match, we need either to rethink this entire      * logic (don't figure out who we are this way) or place the value     * of gethostbyname_p4 into the proctable that gets shipped around (     * as part of the startup, the started process could ship that back      * with its pid).  This would guarantee that the correct name would      * be used, and could be different from the name used to establish      * connections. - WDG     *      * I have fixed this by including the name that the master process     * used to identify this process as an argument pair (-p4yourname host)      * in the argument list given to the remote process creation routine.     * This name is stored in p4_myname_in_procgroup.  We can use this     * for a match if it is non-empty.  This is the name that is used     * to identify the process, and it is the one that is in the     * procgroup table.     *     * 9/19/02: WDG     * There have been problems with this for clusters whose nodes are     * rebooted together, leading to multiple processes having the same     * pid on different nodes.  The use of p4_myname_in_procgroup was     * intended to fix this problem but failed (and in fact made the     * problem worse, according to some bug reports.     *     * To fix and debug this problem, the loop that searches for the matching     * process has been factored into several separate loops, with more     * debugging information generated.  The algorithm is      *   Look for a match between (pi->unix_id,my_unix_id) and     *                             (pi->host_name,p4_myname_in_procgroup).     *   If found, this provides a unique match since (host,pid) are unique.     *     *   If that doesn't work, there is an error!     *     */    n_match           = 0;    match_id          = -1;    /* Question: why not allow localhost? We'll try (should work for       processes all created locally) */    if (p4_myname_in_procgroup[0]        /* && strcmp( p4_myname_in_procgroup, "localhost" ) != 0 */	) {	p4_dprintfl( 88, "myname in procgroup = %s\n", 		     p4_myname_in_procgroup );	for (pi = p4_global->proctable, i = 0; 	     i < p4_global->num_in_proctable; i++, pi++) {	    p4_dprintfl(88, "pid %d ?= %d\n", pi->unix_id, my_unix_id );	    if (pi->unix_id == my_unix_id) {		/* Save match in case hostname test fails */		n_match++;		match_id = i;		if (strcmp( p4_myname_in_procgroup, pi->host_name ) == 0) {		    p4_dprintfl(60,  "get_my_id_from_proc (myname from arg with pi->host_name): returning %d\n",i);		    return (i);		}	    }	}    }    /* The following code is the old code, minus the tests on        p4_myname_in_procgroup */    /* Get a cannonicallized version of the name of this process */    /* gethostbyname returns a pointer to a shared (!) structure.         Rather than being very careful not to change it, we immediately       copy the structure into myh; then get a pointer to that structure       (just to simplify the code below).  This version was originally       due to Ron Brightwell while at SGI (bri@sgi.com) .       Also note that this call is not cheap, so we avoid making it       if we can (that's why we wait until after the simpler loop       on pid and names from the procgroup file).     */    myh = *gethostbyname_p4(p4_global->my_host_name);	    bcopy(myh.h_addr, (char *)&myaddr, myh.h_length);    strcpy(myname, myh.h_name);                            /* If we get here, something is wrong. */    p4_dprintfl( 10, "Could not find process pid=%d host %s in procgroup\n",		 my_unix_id, myname );        p4_dprintfl(60,"p4_get_my_id_from_proc: hostname = :%s:\n", myname);    best_match_id     = -1;    best_match_nchars = 0;    for (pi = p4_global->proctable, i = 0; i < p4_global->num_in_proctable; i++, pi++)    {	p4_dprintfl(88, "pid %d ?= %d\n", pi->unix_id, my_unix_id );	/* Note that after a cluster is booted, all of the nodes may	   assign the pids in the same way.  In this event, matching on the	   pid is not sufficient */	if (pi->unix_id == my_unix_id)	{	    /* Save match in case hostname test fails */	    n_match++;	    match_id = i;	    /* Try to canonicallize the hostnames */            pghp = gethostbyname_p4(pi->host_name);	    p4_dprintfl( 60, ":%s: ?= :%s:\n", pghp->h_name, myname );	    /* We might have localhost.... and the same system.  	       This test won't handle that.  	     */            if (strcmp(pghp->h_name, myname) == 0) /* 8/27/96, llewins@msmail4.hac.com */            {		p4_dprintfl(60,"get_my_id_from_proc: returning %d\n",i);                return (i);            }            /* all nodes on sp1 seem to have same inet address by this test. */            /* After the fix above, the SP1 will probably be fine!! llewins */	    /* Compare the name to the name in the procgroup */	    if (p4_myname_in_procgroup[0] && 		strcmp( p4_myname_in_procgroup, pghp->h_name ) == 0) {		p4_dprintfl(60,"get_my_id_from_proc (myname from arg): returning %d\n",i);                return (i);            }   #           if !defined(SP1)	    else	    {/*		p4_dprintf( "Compare inet addresses %x ?= %x\n",			    *(int *)&myaddr, *(int *)pghp->h_addr ); */                if (bcmp((char *)&myaddr, pghp->h_addr, pghp->h_length) == 0) /* 8/14/96, llewins@msmail4.hac.com */		{		    return (i);		}	    }#           endif /* !SP1 */	    /* Look for a partial match to the name.  What we really need	       is a list of names that this machine is known as (short and	       long, localhost, and alternate networks.) */	    {		char *p1 = pghp->h_name, *p2 = myname;		int  common_chars = 0;		while (*p1 && *p2 && *p1++ == *p2++) common_chars++;		if (common_chars > best_match_nchars) { 		    best_match_nchars = common_chars;		    best_match_id     = i;		}	    }	}    }    /* See comments above on match algorithm */    if (n_match == 1) return match_id;    /* If we reach here, we did not find the process */    if (n_match > 1) {	/* We found too many matches.  Look for a partial match to the name 	   before declaring failure */#if !defined(SYSV_IPC) && !defined(VENDOR_IPC)	/* If there is no comm=shared support, the best match should	   be the one that we want */	if (best_match_nchars > 4) {	    /* the test for four characters is arbitrary, but it helps	       eliminate pathalogical cases */	    p4_dprintfl( 60, "Using best match because no exact match found\n" );	    return best_match_id;	}	else #endif /* !SYSV_IPC && !VENDOR_IPC */	{	    p4_dprintf( "Could not determine the process; my_unix_id = %d my_host=%s\n",		  getpid(), p4_global->my_host_name); 	    p4_dprintf("Probable cause:  local slave on uniprocessor without shared memory\n");	    p4_dprintf("Probable fix:  ensure only one process on %s\n",p4_global->my_host_name);	    p4_dprintf("(on master process this means 'local 0' in the procgroup file)\n");	    p4_dprintf("You can also remake p4 with SYSV_IPC set in the OPTIONS file\n");	    p4_dprintf( "Alternate cause:  Using localhost as a machine name in the progroup\n" );	    p4_dprintf( "file.  The names used should match the external network names.\n" );	}    }    else {	p4_dprintf("process not in process table; my_unix_id = %d my_host=%s\n",		  getpid(), p4_global->my_host_name);	p4_dprintf("Probable cause:  local slave on uniprocessor without shared memory\n");	p4_dprintf("Probable fix:  ensure only one process on %s\n",p4_global->my_host_name);	p4_dprintf("(on master process this means 'local 0' in the procgroup file)\n");	p4_dprintf("You can also remake p4 with SYSV_IPC set in the OPTIONS file\n");	p4_dprintf( "Alternate cause:  Using localhost as a machine name in the progroup\n" );	p4_dprintf( "file.  The names used should match the external network names.\n" );    }    p4_error("p4_get_my_id_from_proc",0);#   endif    return (-2);}int p4_get_my_id( void ){    return (p4_local->my_id);}int p4_get_my_cluster_id( void ){#   if (defined(IPSC860)  &&  !defined(IPSC860_SOCKETS))  ||  \       (defined(CM5)      &&  !defined(CM5_SOCKETS))      ||  \       (defined(NCUBE)    &&  !defined(NCUBE_SOCKETS))    ||  \       (defined(SP1_EUI))                                 ||  \       (defined(SP1_EUIH))                  return(MYNODE());#   else    if (p4_local->my_id == LISTENER_ID)	return (LISTENER_ID);    else	return (p4_global->proctable[p4_local->my_id].slave_idx);#   endif}P4BOOL p4_am_i_cluster_master( void ){    if (p4_local->my_id == LISTENER_ID)	return (0);    else	return (p4_global->proctable[p4_local->my_id].slave_idx == 0);}P4BOOL in_same_cluster( int i, int j ){    return (p4_global->proctable[i].group_id ==	    p4_global->proctable[j].group_id);}P4VOID p4_cluster_shmem_sync( P4VOID **cluster_shmem ){    int myid = p4_get_my_cluster_id();    if (myid == 0)  /* cluster master */	p4_global->cluster_shmem = *cluster_shmem;    p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());    if (myid != 0)	*cluster_shmem = p4_global->cluster_shmem;}#if defined(USE_XX_SHMALLOC)/* This is not machine dependent code but is only used on some machines *//*  Memory management routines from ANSI K&R C, modified to manage  a single block of shared memory.  Have stripped out all the usage monitoring to keep it simple.  To initialize a piece of shared memory:    xx_init_shmalloc(char *memory, unsigned nbytes)  Then call xx_shmalloc() and xx_shfree() as usual.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -