📄 ipsc.c
字号:
/* $Header: /home/harrison/c/tcgmsg/ipcv4.0/RCS/ipsc.c,v 1.1 91/12/06 17:26:39 harrison Exp Locker: harrison $ *//* Toolkit interface for the iPSC-2 and simulator*/#include <stdio.h>#include "sndrcv.h"#ifdef EVENTLOG#include "evlog.h"#endifextern char* malloc();/* Declarations of routines used from the iPSC communications library */#ifdef DELTA#include <mesh.h>#else#include <cube.h>#endifextern char *memalign();static long nxtval_buffer[2]; /* Used by handler for nxtval service */static void nxtval_handler();static long nxtval_server;#define TYPE_NXTVAL 32768 /* Type of messages for next value */#define TYPE_NXTVAL_REPLY 32769/* So that can easily wait for message of specific type and node the sender packs the user type and requested node to form an internal type with MAKETYPE. GETTYPE and GETNODE extract the user type and originating node, respectively.*/#define MAKETYPE(type, node) ((long) ((type) | ((node) << 17)))#define GETTYPE(ttype) ((long) ((ttype) & 0xffff))#define GETNODE(ttype) ((long) (((ttype) >> 17) & 0xffff))/* Macros for checking node and type - true if out of range */#define CHKNODE(node) ( ((node) < 0) || ((node) > NNODES_()) )#define CHKTYPE(type) ( ((type) < 1) || ((type) > 32767) )/* Global variables */#define DEBUG_ DEBUGstatic long DEBUG=0; /* debug flag ... see setdbg */#define MAX_Q_LEN 2048 /* Maximum no. of outstanding messages */static long n_in_msg_q = 0; /* No. in the message q */static struct msg_q_struct{ long msg_id; long node; long type; long lenbuf; long snd; long from;} msg_q[MAX_Q_LEN];/***********************************************************/long NODEID_()/* Return number of the calling process ... at the moment this is just the same as the Intel numbering*/{ return mynode();}void Error(string, code) char *string; long code;/* Error handler*/{ (void) fflush(stdout); (void) fflush(stderr); (void) fprintf(stderr, "%3d:%s %ld(%x)\n", NODEID_(), string, code, code); (void) perror("system message"); (void) fflush(stdout); (void) fflush(stderr);#ifdef DELTA killproc((long) -1, (long) 0);#else killcube((long) -1, (long) -1);#endif}long NNODES_()/* Return number of USER processes.*/{ return numnodes();}static long firsttime=0; /* Reference for timer */static void MtimeReset() /* Sets timer reference */{ firsttime = (long) mclock();}long MTIME_()/* Return elapsed time in CENTI seconds from some abitrary origin*/{ static long firstcall = 1; if (firstcall) { firstcall = 0; MtimeReset(); } return (long) ((mclock() - firsttime) / 10);}void SND_(type, buf, lenbuf, node, sync) long *type; char *buf; long *lenbuf; long *node; long *sync;/* long *type = user defined integer message type (input) char *buf = data buffer (input) long *lenbuf = length of buffer in bytes (input) long *node = node to send to (input) long *sync = flag for sync(1) or async(0) communication (input)*/{ long me = NODEID_(); long ttype = MAKETYPE(*type, me); if (CHKTYPE(*type)) Error("SND_: invalid type specified",*type); if (CHKNODE(*node)) Error("SND_: invalid node specified",*node); if (DEBUG) { (void) printf("SND_: node %ld sending to %ld, len=%ld, type=%ld, sync=%ld\n", me, *node, *lenbuf, *type, *sync); (void) fflush(stdout); }#ifdef EVENTLOG evlog(EVKEY_BEGIN, EVENT_SND, EVKEY_MSG_LEN, *lenbuf, EVKEY_MSG_FROM, me, EVKEY_MSG_TO, *node, EVKEY_MSG_TYPE, *type, EVKEY_MSG_SYNC, *sync, EVKEY_LAST_ARG);#endif if (*sync) csend(ttype, buf, *lenbuf, *node, 0); else { if (n_in_msg_q >= MAX_Q_LEN) Error("SND: overflowing async Q limit", n_in_msg_q); msg_q[n_in_msg_q].msg_id = isend(ttype, buf, *lenbuf, *node, 0); msg_q[n_in_msg_q].snd = 1; if (DEBUG) { (void) printf("SND: me=%ld, to=%ld, len=%ld, msg_id=%ld, ninq=%ld\n", me, *node, *lenbuf, msg_q[n_in_msg_q].msg_id, n_in_msg_q); (void) fflush(stdout); } n_in_msg_q++; }#ifdef EVENTLOG evlog(EVKEY_END, EVENT_SND, EVKEY_LAST_ARG);#endif}void RCV_(type, buf, lenbuf, lenmes, nodeselect, nodefrom, sync) long *type; char *buf; long *lenbuf; long *lenmes; long *nodeselect; long *nodefrom; long *sync;/* long *type = user defined type of received message (input) char *buf = data buffer (output) long *lenbuf = length of buffer in bytes (input) long *lenmes = length of received message in bytes (output) (exceeding receive buffer is hard error) long *nodeselect = node to receive from (input) -1 implies that any pending message of the specified type may be received long *nodefrom = node message is received from (output) long *sync = flag for sync(1) or async(0) receipt (input)*/{ long me = NODEID_(); long ttype; static long node = 0; /* For fairness in rcv from anyone */ if (CHKTYPE(*type)) Error("RCV_: invalid type specified",*type); if (*nodeselect != -1) { if (CHKNODE(*nodeselect)) Error("RCV_: invalid node specified",*nodeselect); ttype = MAKETYPE(*type, *nodeselect); } else { ttype = -1; /* Any node, check type later */ } if (DEBUG) { (void) printf("RCV_: node %ld receiving from %ld, len=%ld, type=%ld, sync=%ld\n", me, *nodeselect, *lenbuf, *type, *sync); (void) fflush(stdout); } #ifdef EVENTLOG evlog(EVKEY_BEGIN, EVENT_RCV, EVKEY_MSG_FROM, *nodeselect, EVKEY_MSG_TO, me, EVKEY_MSG_TYPE, *type, EVKEY_MSG_SYNC, *sync, EVKEY_LAST_ARG);#endif if (*sync) { if (*nodeselect == -1) { /* Receive from anyone. To do this efficiently and preserve the type matching first wait for a message of any type to have arrived. Then if it is of the correct type we are in business. Otherwise we have an O(P) process where we loop thru all processors looking for messages ... ugh. */ cprobe((long) -1); /* Yuck ... NX makes no attempt at fairness ... it always searches starting at node 0 ... gotta live with it or accept an O(P) cost even if only one message is pending */ ttype = infotype(); if (GETTYPE(ttype) != *type) { long nn = NNODES_(); while (1) { ttype = MAKETYPE(*type, node); if (iprobe(ttype)) break; else { node = (node + 1) % nn; if (node == 0) {flick(); flick(); flick();} } } } } crecv(ttype, buf, *lenbuf); *nodefrom = infonode(); /* Get source node */ ttype = infotype(); /* Get type */ *lenmes = infocount(); /* Get length */ if (*lenmes > *lenbuf) Error("RCV_: out of range length on received message",*lenmes); if (GETTYPE(ttype) != *type) Error("RCV_: type mismatch for received message",GETTYPE(ttype)); if (GETNODE(ttype) != *nodefrom) Error("RCV_: mismatch of nodefrom and node packed in received type", GETNODE(ttype)); if (*nodeselect != -1 && *nodefrom != *nodeselect) Error("RCV_: received message from wrong node!",*nodefrom); } else { /* Note that essentially NO checking can be done here as the info is just not available. Set the unknown return values to invalid values. Checking is done later when the asynch I/O completes */ /* !!!! Note that that asynchronous receive from anyone breaks unless an explicit syncronization is done if there is any possibility of a message of a different type arriving. The synchronous code does not suffer this problem !!! */ if (n_in_msg_q >= MAX_Q_LEN) Error("RCV: overflowing async Q limit", n_in_msg_q); msg_q[n_in_msg_q].msg_id = irecv(ttype, buf, *lenbuf); msg_q[n_in_msg_q].node = *nodeselect; msg_q[n_in_msg_q].type = *type; msg_q[n_in_msg_q].lenbuf = *lenbuf; msg_q[n_in_msg_q].snd = 0; if (DEBUG) { (void) printf("RCV: me=%ld, from=%ld, len=%ld, msg_id=%ld, ninq=%ld\n", me, *nodeselect, *lenbuf, msg_q[n_in_msg_q].msg_id, n_in_msg_q); (void) fflush(stdout); } *lenmes = (long) -1; n_in_msg_q++; *nodefrom = (long) *nodeselect; }#ifdef EVENTLOG evlog(EVKEY_END, EVENT_RCV, EVKEY_MSG_FROM, *nodefrom, EVKEY_MSG_LEN, *lenmes, EVKEY_LAST_ARG);#endif}void PBEGINF_(){ PBEGIN_();}void PBEGIN_(){ char workdir[256], *eventfile; long start = MTIME_(); long type = 1; DEBUG = 0; if (DEBUG) { (void) printf("node %ld called pbeginf\n",NODEID_()); (void) fflush(stdout); }#ifndef DELTA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -