📄 p4_md.c
字号:
* == 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 + -