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

📄 p4_md.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 3 页
字号:
 * == 0, then n is the number of bytes to claim as globally-shared memory * (from which routines can ask for shared memory).  In this case the routine * returns the address of the allocated block (NULL, if an allocation failure * occurs). * * else if typ == 1, then n is taken to be the amount of shared memory * requested.  In this case, the routine returns the address of a block of at * least n charecters in length. * * else if typ == 2, then the routine is being asked to return the address of * the globally- shared block of memory. * * The view of shared memory supported by xx_malloc is that a single massive chunk * of memory is acquired and handed out by xx_malloc calls with 1 as first * argument. */struct mem_blk{    char *next;    int l_mem;    MD_lock_t MEM;    int pad;			/* pad out to 8-byte boundary */};char *xx_malloc(typ, n)int typ, n;{    static struct mem_blk *glob_mem = (struct mem_blk *) NULL;    static int l_mem = 0;    char *rc;    int i;    char *c;    /* bbn stuff */#define SHMEM_BASE 0x401000    vm_address_t shmem_seg;    union cluster_status cl_stat;    int clus_size;    int blk_cnt, ok;    /* end bbn stuff */    switch (typ)    {      case 0:			/* initialize */	/* pad & malloc */	/*	 * printf("clus_size = %d, &clus_size = %d\n",clus_size,&clus_size);	 */	cluster_stat(HOME_CLUSTER, GET_NODE_LIST, &cl_stat, &clus_size);	/*	 * printf("clus_size = %d, &clus_size = %d\n",clus_size,&clus_size);	 */	blk_cnt = ((n / clus_size) / vm_page_size) + 1;	/* printf("n = %d,page size = %d  ",n,vm_page_size); */	/*	 * printf("clus_size = %d, blk_cnt = %d\n", clus_size,blk_cnt);	 */	ok = 1;	for (i = 0; (i < clus_size) && ok; i++)	{	    shmem_seg = SHMEM_BASE + (vm_page_size * blk_cnt) * i;	    if (vm_allocate_and_bind(task_self(), &shmem_seg, blk_cnt * vm_page_size,				     P4_FALSE, i) != KERN_SUCCESS)	    {		printf("vm_allocate_and_bind failed\n");		ok = 0;	    }	    else if (vm_inherit(task_self(), shmem_seg, blk_cnt * vm_page_size,				VM_INHERIT_SHARE) != KERN_SUCCESS)	    {		printf("vm_inherit failed\n");		ok = 0;	    }	}	if (ok)	{			/* everything succeeded */	    glob_mem = (struct mem_blk *) SHMEM_BASE;	    glob_mem->next = (char *) (SHMEM_BASE + sizeof(struct mem_blk));	    glob_mem->l_mem = n;	    rc = glob_mem->next;	    MD_lock_init(&glob_mem->MEM);	}	break;      case 1:	i = (n + 7) & (~007);	MD_lock(&glob_mem->MEM);	if (glob_mem->l_mem < i)	{	    p4_dprintf("*** global allocation failure ***\n");	    p4_dprintf("*** attempted %d bytes, %d left\n",		       i, glob_mem->l_mem);	    rc = NULL;	    MD_unlock(&glob_mem->MEM);	    p4_error("xx_malloc: global alloc failed", i);	}	else	{	    rc = glob_mem->next;	    glob_mem->next += i;	    glob_mem->l_mem -= i;	    /* printf("allocated %d bytes of shared memory at %x\n",i,rc); */	}	MD_unlock(&glob_mem->MEM);	break;      case 2:	rc = (char *) glob_mem;	break;      default:	printf("*** illegal call to xx_malloc *** typ=%d\n", typ);    }    return (rc);}#endif#if defined(TC_2000)/* * xx_malloc is a memory allocation routine.  It is called in two ways: * if typ == 1, then n is taken to be the amount of shared memory * requested.  In this case, the routine returns the address of a block of at * least n charecters in length.  We round up to cache-line size, since we * may have specified cache attributes.... * * else if typ == 2, then n is interpreted as a character pointer, pointing to * a string containing a filename that is used for rendesvous as a * memory-mapped-file, thus allowing unrelated processes to allocate shared * memory with each other. * * else if typ == 3, then heapsync() is called to help processes avoid doing * shared memory map-ins at reference time. * */char *xx_malloc(typ, n)int typ, n;{    char *mem_ptr, *mapped_filename;    int alloc_chunk;    switch (typ)    {      case 1:	/* pad to multiple of cache-line size */	alloc_chunk = (n + 17) & (~017);	/*	 * B printf("allocated %d bytes of shared memory\n",i); printf("at	 * %x\n",mem_ptr); E	 */	/* gag - refer to our global at the top of the file */	if ((mem_ptr = heapmalloc(characteristic, locality, alloc_chunk)) == NULL)	    p4_dprintf("*** global allocation failure - general ***\n");	/* reset hints to "defaults" */	characteristic = HEAP_INTERLEAVED;	locality = HEAP_ANYWHERE;	/* $$$ should be HEAP_SCATTERED */	break;      case 2:	heapfile((char *) n);	break;      case 3:	heapsync();	break;      default:	printf("*** illegal call to xx_malloc *** typ=%d\n", typ);    }    return (mem_ptr);}#endif#if defined(IPSC860)struct p4_msg *MD_i860_recv()/* Low level ipsc 860 message receive routine. * * All messages should be of the p4_msg type. * * Blocks until it receives a message. * * If the type is "ACK_REQUEST", then send back and "ACK_REPLY", to * confirm that the message was received.  If the message is of this * type, than it is sent in the struct tmsg form, to encapsulate the * user's chosen type of message, which gets ignored in this routine. */{    long type;    int proc = NODE_PID, node, alloc_size, msg_size;    struct p4_msg *m;		/* WARNING: deallocate above  */    char ack = 'a';    /*     * Probe to see how big the incoming message is.  Block until that     * message comes in.  Allocate it, and receive it.  All the p4_msg     * information should automatically, since the message is a p4_msg type.     */    p4_dprintfl(20, "receiving a msg via i860 crecv\n");    cprobe(ANY_P4TYPE_IPSC);    alloc_size = (int) infocount();    type = (int) infotype();    node = (int) infonode();    msg_size = alloc_size - sizeof(struct p4_msg) + sizeof(char *);    m = alloc_p4_msg(msg_size);    crecv(ANY_P4TYPE_IPSC, (char *) m, (long) alloc_size);    p4_dprintfl(10, "received msg via i860 crecv from=%d type=%d \n",m->from,m->type);    /*     * If the type is "ACK_REQUEST", fire off the reply. If sender was the     * host, send it to the procid of the host.     */    if (type == ACK_REQUEST_IPSC)    {	p4_dprintfl(30, "sending ack to %d\n", m->from);	csend(ACK_REPLY_IPSC, &ack, sizeof(char), node, proc);	p4_dprintfl(30, "sent ack to %d\n", m->from);    }    return (m);}int MD_i860_send(m)struct p4_msg *m;/* * Send the message, nonblocking, no wait for acknowledgement of receipt. */{    int proc = NODE_PID, to;    char buf;			/* buffer for the ack message */    int len;    to = p4_local->conntab[m->to].port;    p4_dprintfl(20, "sending msg of type %d from %d to %d via i860 send\n",m->type,m->from,m->to);    len = m->len + sizeof(struct p4_msg) - sizeof(char *);    if (!(m->ack_req & P4_ACK_REQ_MASK))    {	m->msg_id = (int) isend((long) NO_TYPE_IPSC, m, (long) len, (long) to, (long) proc);	(p4_global->cube_msgs_out)++;	p4_dprintfl(10, "sent msg of type %d from %d to %d via i860 isend\n",m->type,m->from,m->to);    }    else    {	/* Send a message, asking for an acknowledgement of receipt. */	csend((long) ACK_REQUEST_IPSC, m, (long) len, (long) to, (long) proc);	m->msg_id = -1;		/* already waited for by csend */	/* Wait for the acknowledgement. */	p4_dprintfl(30, "waiting for ack from %d\n", m->to);	crecv((long) ACK_REPLY_IPSC, &buf, (long) sizeof(char));	p4_dprintfl(30, "received ack from %d\n", m->to);	p4_dprintfl(10, "sent msg of type %d from %d to %d via i860 csend\n",m->type,m->from,m->to);    }}P4BOOL MD_i860_msgs_available(){    P4BOOL rc;    rc = (P4BOOL) iprobe(ANY_P4TYPE_IPSC);    return (rc);}/* endif for ipsc860 */#endif#if defined(SP1_EUI)MD_eui_send(m)struct p4_msg *m;{    int nbytes;    char ack_msg;    int send_len,acklen = sizeof(char);    int ack_reply_type = ACK_REPLY_EUI;    p4_dprintfl(20,"sending to %d via eui\n",m->to);    send_len = m->len+sizeof(struct p4_msg)-sizeof(char *);    mpc_bsend(m,send_len,m->to,m->type);    p4_dprintfl(10,"sent msg to %d via eui\n",m->to);    if (m->ack_req & P4_ACK_REQ_MASK)    {        acklen = sizeof(char);	mpc_brecv(&ack_msg,acklen,&m->to,&ack_reply_type,&nbytes);    }}struct p4_msg *MD_eui_recv(){    int nbytes,from,type,acklen,acktype,msg_size,alloc_size;    struct p4_msg hdr, *m;    char ack_msg;    from = ANY_P4TYPE_EUI;    type = ANY_P4TYPE_EUI;    mpc_probe(&from,&type,&alloc_size);    msg_size = alloc_size - sizeof(struct p4_msg) + sizeof(char *);    m = alloc_p4_msg(msg_size);    mpc_brecv(m,alloc_size,&from,&type,&nbytes);    if (m->ack_req & P4_ACK_REQ_MASK)    {	acklen = sizeof(char);        acktype = ACK_REPLY_EUI;	mpc_bsend(&ack_msg,acklen,m->from,ACK_REPLY_EUI);    }    return(m);}MD_eui_msgs_available(){    int numbytes;    int from = ANY_P4TYPE_EUI;    int type = ANY_P4TYPE_EUI;    mpc_probe(&from,&type,&numbytes);    if (numbytes == -1)	return P4_FALSE;    else	return P4_TRUE;}/* end of include for EUI */#endif#if defined(SP1_EUIH)MD_euih_send(m)struct p4_msg *m;{    int nbytes;    char ack_msg;    int send_len,acklen = sizeof(char);    int ack_reply_type = ACK_REPLY_EUIH;    p4_dprintfl(20,"sending to %d via euih\n",m->to);    send_len = m->len+sizeof(struct p4_msg)-sizeof(char *);    mp_bsend(m,&send_len,&(m->to),&(m->type));    p4_dprintfl(10,"sent msg to %d via euih\n",m->to);    if (m->ack_req & P4_ACK_REQ_MASK)    {	acklen = sizeof(char);	mp_brecv(&ack_msg,&acklen,&(m->to),&ack_reply_type,&nbytes);    }}struct p4_msg *MD_euih_recv(){    int nbytes,from,type,acklen,acktype,msg_size,alloc_size;    struct p4_msg hdr, *m;    char ack_msg;    from = ANY_P4TYPE_EUIH;    type = ANY_P4TYPE_EUIH;    mp_probe(&from,&type,&alloc_size);    msg_size = alloc_size - sizeof(struct p4_msg) + sizeof(char *);    m = alloc_p4_msg(msg_size);    mp_brecv(m,&alloc_size,&from,&type,&nbytes);    if (m->ack_req & P4_ACK_REQ_MASK)    {	acklen = sizeof(char);	acktype = ACK_REPLY_EUIH;	mp_bsend(&ack_msg,&acklen,&(m->from),&acktype);    }    return(m);}MD_euih_msgs_available(){    int numbytes;    int from = ANY_P4TYPE_EUIH;    int type = ANY_P4TYPE_EUIH;    mp_probe(&from,&type,&numbytes);    if (numbytes == -1)	return P4_FALSE;    else	return P4_TRUE;}/* end of include for SP1_EUIH */#endif#if defined(CM5)struct p4_msg *MD_CM5_recv()/* Low level CM-5 message receive routine. * * All messages should be of the p4_msg type. * * Blocks until it receives a message. * * If the type is "ACK_REQUEST", then send back and "ACK_REPLY", to * confirm that the message was received.  If the message is of this * type, than it is sent in the struct tmsg form, to encapsulate the * user's chosen type of message, which gets ignored in this routine. */{    int type, node, alloc_size, msg_size;    struct p4_msg *m;		/* WARNING: deallocate above  */    char ack = 'a';    /*     * Probe to see how big the incoming message is.  Block until that     * message comes in.  Allocate it, and receive it.  All the p4_msg     * information should automatically, since the message is a p4_msg type.     */    p4_dprintfl(20, "receiving a msg via cm-5 recv\n");    CMMD_msg_pending(CMMD_ANY_NODE, CMMD_ANY_TAG);    alloc_size = CMMD_bytes_received();    type = CMMD_msg_tag();    node = CMMD_msg_sender();    msg_size = alloc_size - sizeof(struct p4_msg) + sizeof(char *);    m = alloc_p4_msg(msg_size);    CMMD_receive(node, type, (void *) m, alloc_size);    p4_dprintfl(10, "received msg via cm-5 recv from=%d type=%d \n",m->from,m->type);    if (type == ACK_REQUEST_CM5)    {	p4_dprintfl(30, "sending ack to %d\n", m->from);	CMMD_send_noblock(m->from,ACK_REPLY_CM5,&ack,sizeof(char));	p4_dprintfl(30, "sent ack to %d\n", m->from);    }    return (m);}int MD_CM5_send(m)struct p4_msg *m;{    int to,len;    char buf;			/* buffer for the ack message */    to = p4_local->conntab[m->to].port;    p4_dprintfl(20, "sending msg of type %d from %d to %d via cm5 send\n",m->type,m->from,m->to);    len = m->len + sizeof(struct p4_msg) - sizeof(char *);    if (!(m->ack_req & P4_ACK_REQ_MASK))    {	CMMD_send_noblock(to, NO_TYPE_CM5, (void *) m, len);	p4_dprintfl(10, "sent msg of type %d from %d to %d via cm5 send\n",m->type,m->from,m->to);    }    else    {	/* Send a message, asking for an acknowledgement of receipt. */	CMMD_send_noblock(to, ACK_REQUEST_CM5, (void *) m, len);	/* Wait for the acknowledgement. */	p4_dprintfl(30, "waiting for ack from %d\n", m->to);        CMMD_receive(to, ACK_REPLY_CM5, (void *) &buf, sizeof(char));	p4_dprintfl(30, "received ack from %d\n", m->to);	p4_dprintfl(10, "sent msg of type %d from %d to %d via cm5 csend\n",m->type,m->from,m->to);    }}P4BOOL MD_CM5_msgs_available(){    P4BOOL rc;    rc = CMMD_msg_pending(CMMD_ANY_NODE,CMMD_ANY_TAG);    return (rc);}/* endif for cm5 */#endif#if defined(NCUBE)struct p4_msg *MD_NCUBE_recv()/* Low level NCUBE message receive routine. * * All messages should be of the p4_msg type. * * Blocks until it receives a message. * * If the type is "ACK_REQUEST", then send back and "ACK_REPLY", to * confirm that the message was received.  If the message is of this * type, than it is sent in the struct tmsg form, to encapsulate the * user's chosen type of message, which gets ignored in this routine. */{    int type, node, alloc_size, msg_size, unused_flag;    struct p4_msg *m;		/* WARNING: deallocate above  */    char ack = 'a';    /*     * Probe to see how big the incoming message is.  Block until that     * message comes in.  Allocate it, and receive it.  All the p4_msg     * information should automatically, since the message is a p4_msg type.     */    p4_dprintfl(20, "receiving a msg via ncube recv\n");    node = NCUBE_ANY_NODE;    type = NCUBE_ANY_TAG;    alloc_size = -1;    while (alloc_size < 0)    {        alloc_size = ntest(&node,&type);    }    msg_size = alloc_size - sizeof(struct p4_msg) + sizeof(char *);    m = alloc_p4_msg(msg_size);    nread(m, alloc_size, &node,  &type, &unused_flag);    p4_dprintfl(10, "received msg via ncube recv from=%d type=%d \n",m->from,m->type);    if (type == ACK_REQUEST_NCUBE)    {	p4_dprintfl(30, "sending ack to %d\n", m->from);	nwrite(&ack, sizeof(char), m->from, ACK_REPLY_NCUBE, &unused_flag);	p4_dprintfl(30, "sent ack to %d\n", m->from);    }    return (m);}int MD_NCUBE_send(m)struct p4_msg *m;{    int rc,to,len,type,unused_flag;    char buf;			/* buffer for the ack message */    if (m->to == 0xffff)  /* NCUBE broadcast */        to = 0xffff;    else	to = p4_local->conntab[m->to].port;    p4_dprintfl(20, "sending msg of type %d from %d to %d via NCUBE send\n",		m->type,m->from,m->to);    len = m->len + sizeof(struct p4_msg) - sizeof(char *);    if (!(m->ack_req & P4_ACK_REQ_MASK))    {	rc = nwrite(m, len, to, NO_TYPE_NCUBE, &unused_flag);        if (rc < 0)        {            p4_dprintf("nwrite failed for msg of length %d from %d to %d \n",                        len,m->from,m->to);            p4_error("exiting due to failed nwrite",rc);

⌨️ 快捷键说明

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