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

📄 ipsc.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $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 + -