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

📄 p4_utils.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 3 页
字号:
#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();#endifvoid p4_post_init(){    /* This routine can be called to do any further initialization after p4       has itself been intialized. *//* undef preconnect since we do not want to do it for mpd */#undef P4_PRECONNECT #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(){    strcpy(hold_patchlevel,P4_PATCHLEVEL);    return(hold_patchlevel);}char *p4_machine_type(){    strcpy(hold_machine_type,P4_MACHINE_TYPE);    return(hold_machine_type);}int p4_initenv(argc, argv)int *argc;char **argv;{    int i, rc;    char *env_value;    int p4_globmemsize;    P4BOOL am_slave = P4_FALSE;    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;    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_local  = NULL;    p4_global = NULL;    /* Note that for mpd everyone is a master - RL  */    if (am_slave)    {	rc = rm_start(argc, argv);    }    else    {	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(n)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)\n",n);    return (rc);}P4VOID p4_shfree(p)P4VOID *p;{    MD_shfree(p);}int p4_num_cluster_ids(){    return (p4_global->local_slave_count + 1);}int p4_num_total_ids(){    return (p4_global->num_in_proctable);}int p4_num_total_slaves(){    return (p4_global->num_in_proctable - 1);}P4VOID p4_global_barrier(type)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(numids, ids)int *numids, 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(start, end)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(){    int i, my_unix_id;    int n_match, match_id;    struct proc_info *pi;    struct hostent *myhp, *pghp;    struct in_addr myaddr;       /* 8/14/96, llewins@msmail4.hac.com */    char myname[MAXHOSTNAMELEN]; /* 9/10/96, llewins@msmail4.hac.com */    struct hostent myh;			/* 7/12/95, bri@sgi.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);    /* 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)      */    myh = *gethostbyname_p4(p4_global->my_host_name);	/* 7/12/95, bri@sgi.com */    myhp = &myh;					/* 7/12/95, bri@sgi.com */    bcopy(myhp->h_addr, (char *)&myaddr, myhp->h_length); /* 8/14/96, llewins@msmail4.hac.com */    strcpy(myname, myhp->h_name);                         /* 9/10/96, llewins@msmail4.hac.com */    p4_dprintfl(60,"p4_get_my_id_from_proc: hostname = :%s:\n", myname);/*    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     */    n_match = 0;    match_id = -1;    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 incase hostname test fails */	    n_match++;	    match_id = i;            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 */#           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	}    }    /* See comments above on match algorithm */    if (n_match == 1) return match_id;    /* If we reach here, we did not find the process */    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(){    return (p4_local->my_id);}int p4_get_my_cluster_id(){#   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(){    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(i, j)int i, j;{    return(P4_FALSE);		/* for MPD for now, no clusters *//*    return (p4_global->proctable[i].group_id ==	    p4_global->proctable[j].group_id);	    */}P4VOID p4_cluster_shmem_sync(cluster_shmem)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.*//* IBM AIX 4.3.3 defined ALIGNMENT in sys/socket.h (!) */#define LOG_ALIGN 6#define P4_MEM_ALIGNMENT (1 << LOG_ALIGN)/* P4_MEM_ALIGNMENT is assumed below to be bigger than sizeof(p4_lock_t) +   sizeof(Header *), so do not reduce LOG_ALIGN below 4 */union header{    struct    {	union header *ptr;	/* next block if on free list */	unsigned size;		/* size of this block */    } s;    char align[P4_MEM_ALIGNMENT];   /* Align to ALIGNMENT byte boundary */};typedef union header Header;static Header **freep;		/* pointer to pointer to start of free list */static p4_lock_t *shmem_lock;	/* Pointer to lock */P4VOID xx_init_shmalloc(memory, nbytes)char *memory;unsigned nbytes;/*  memory points to a region of shared memory nbytes long.  initialize the data structures needed to manage this memory*/{    int nunits = nbytes >> LOG_ALIGN;

⌨️ 快捷键说明

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