📄 p4_utils.c
字号:
#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 + -