*** empty log message ***
authorJosh Yelon <jyelon@uiuc.edu>
Mon, 28 Jul 1997 17:44:36 +0000 (17:44 +0000)
committerJosh Yelon <jyelon@uiuc.edu>
Mon, 28 Jul 1997 17:44:36 +0000 (17:44 +0000)
src/langs/pvmc/pvm3.h [new file with mode: 0644]
src/langs/pvmc/pvmc.h [new file with mode: 0644]
src/langs/pvmc/pvmc_buf.c [new file with mode: 0644]
src/langs/pvmc/pvmc_comm.c [new file with mode: 0644]
src/langs/pvmc/pvmc_conv.c [new file with mode: 0644]
src/langs/pvmc/pvmc_groups.c [new file with mode: 0644]
src/langs/pvmc/pvmc_main.c [new file with mode: 0644]
src/langs/pvmc/pvmc_pack.c [new file with mode: 0644]
src/langs/pvmc/pvmctest.c [new file with mode: 0644]

diff --git a/src/langs/pvmc/pvm3.h b/src/langs/pvmc/pvm3.h
new file mode 100644 (file)
index 0000000..3260ced
--- /dev/null
@@ -0,0 +1,204 @@
+#ifndef __PVM3_H__
+#define __PVM3_H__
+
+struct pvmhostinfo {
+       int hi_tid;                     /* pvmd tid */
+       char *hi_name;          /* host name */
+       char *hi_arch;          /* host arch */
+       int hi_speed;           /* cpu relative speed */
+};
+
+struct pvmtaskinfo {
+       int ti_tid;                             /* task id */
+       int ti_ptid;                    /* parent tid */
+       int ti_host;                    /* pvmd tid */
+       int ti_flag;                    /* status flags */
+       char *ti_a_out;                 /* a.out name */
+       int ti_pid;                             /* task (O/S dependent) process id */
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void pvmc_init(void);
+int pvm_mkbuf(int encoding);
+int pvm_freebuf(int bufid);
+int pvm_getsbuf(void);
+int pvm_setsbuf(int bufid);
+int pvm_getrbuf(void);
+int pvm_setrbuf(int bufid);
+int pvm_initsend(int encoding);
+int pvm_bufinfo(int bufid, int *bytes, int *msgtag, int *tid);
+
+int pvm_send(int tid, int tag);
+int pvm_mcast(int *tids, int ntask, int msgtag);
+int pvm_nrecv(int tid, int tag);
+int pvm_recv(int tid, int tag);
+int pvm_probe(int tid, int tag);
+
+int pvm_mytid(void);
+int pvm_exit(void);
+int pvm_kill(int tid);
+int pvm_spawn(char *task, char **argv, int flag,
+             char *where, int ntask, int *tids);
+int pvm_parent(void);
+int pvm_config(int *nhost, int *narch, struct pvmhostinfo **hostp);
+int pvm_tasks(int which, int *ntask, struct pvmtaskinfo **taskp);
+int pvm_setopt(int what, int val);
+int pvm_gsize(char *group);
+int pvm_gettid(char *group, int inum);
+
+int pvm_upkbyte(char *cp, int cnt, int std);
+int pvm_upkcplx(float *xp, int cnt, int std);
+int pvm_upkdcplx(double *zp, int cnt, int std);
+int pvm_upkdouble(double *dp, int cnt, int std);
+int pvm_upkfloat(float *fp, int cnt, int std);
+int pvm_upkint(int *np, int cnt, int std);
+int pvm_upklong(long *np, int cnt, int std);
+int pvm_upkshort(short *np, int cnt, int std);
+int pvm_upkuint(unsigned int *np, int cnt, int std);
+int pvm_upkulong(unsigned long *np, int cnt, int std);
+int pvm_upkushort(unsigned short *np, int cnt, int std);
+int pvm_upkstr(char *cp);
+
+int pvm_pkbyte(char *cp, int cnt, int std);
+int pvm_pkcplx(float *xp, int cnt, int std);
+int pvm_pkdcplx(double *zp, int cnt, int std);
+int pvm_pkdouble(double *dp, int cnt, int std);
+int pvm_pkfloat(float *fp, int cnt, int std);
+int pvm_pkint(int *np, int cnt, int std);
+int pvm_pklong(long *np, int cnt, int std);
+int pvm_pkshort(short *np, int cnt, int std);
+int pvm_pkuint(unsigned int *np, int cnt, int std);
+int pvm_pkulong(unsigned long *np, int cnt, int std);
+int pvm_pkushort(unsigned short *np, int cnt, int std);
+int pvm_pkstr(char *cp);
+
+int pvm_bcast(const char *group, int msgtag);
+int pvm_joingroup(const char *group);
+int pvm_lvgroup(const char *group);
+int pvm_barrier(const char *group, int count);
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/* defines from pvm3.h */
+
+/*
+*      Data packing styles for pvm_initsend()
+*/
+
+#define        PvmDataDefault  0
+#define        PvmDataRaw              1
+#define        PvmDataInPlace  2
+#define        PvmDataFoo              3
+
+/*
+*      pvm_spawn options
+*/
+
+#define        PvmTaskDefault  0
+#define        PvmTaskHost             1       /* specify host */
+#define        PvmTaskArch             2       /* specify architecture */
+#define        PvmTaskDebug    4       /* start task in debugger */
+#define        PvmTaskTrace    8       /* process generates trace data */
+/* for MPP ports */
+#define        PvmMppFront             16      /* spawn task on service node */
+#define        PvmHostCompl    32      /* complement host set */
+
+/*
+*      pvm_notify types
+*/
+
+#define        PvmTaskExit             1       /* on task exit */
+#define        PvmHostDelete   2       /* on host fail/delete */
+#define        PvmHostAdd              3       /* on host startup */
+
+/*
+*      for pvm_setopt and pvm_getopt
+*/
+
+#define        PvmRoute                        1       /* routing policy */
+#define                PvmDontRoute            1       /* don't allow direct task-task links */
+#define                PvmAllowDirect          2       /* allow direct links, but don't request */
+#define                PvmRouteDirect          3       /* request direct links */
+#define        PvmDebugMask            2       /* debugmask */
+#define        PvmAutoErr                      3       /* auto error reporting */
+#define        PvmOutputTid            4       /* stdout destination for children */
+#define        PvmOutputCode           5       /* stdout message tag */
+#define        PvmTraceTid                     6       /* trace destination for children */
+#define        PvmTraceCode            7       /* trace message tag */
+#define        PvmFragSize                     8       /* message fragment size */
+#define        PvmResvTids                     9       /* allow reserved message tids and codes */
+#define        PvmSelfOutputTid        10      /* stdout destination for task */
+#define        PvmSelfOutputCode       11      /* stdout message tag */
+#define        PvmSelfTraceTid         12      /* trace destination for task */
+#define        PvmSelfTraceCode        13      /* trace message tag */
+#define        PvmShowTids                     14      /* pvm_catchout prints task ids with output */
+#define        PvmPollType                     15      /* shared memory wait method */
+#define                PvmPollConstant 1
+#define                PvmPollSleep    2
+#define        PvmPollTime                     16      /* time before sleep if PvmPollSleep */
+
+/*
+*      for pvm_[sg]ettmask
+*/
+
+#define        PvmTaskSelf             0       /* this task */
+#define        PvmTaskChild    1       /* (future) child tasks */
+
+/*
+*      Libpvm error codes
+*/
+
+#define        PvmOk                   0       /* Error 0 */
+#define        PvmBadParam             -2      /* Bad parameter */
+#define        PvmMismatch             -3      /* Count mismatch */
+#define        PvmOverflow             -4      /* Value too large */
+#define        PvmNoData               -5      /* End of buffer */
+#define        PvmNoHost               -6      /* No such host */
+#define        PvmNoFile               -7      /* No such file */
+#define        PvmNoMem                -10     /* Malloc failed */
+#define        PvmBadMsg               -12     /* Can't decode message */
+#define        PvmSysErr               -14     /* Can't contact local daemon */
+#define        PvmNoBuf                -15     /* No current buffer */
+#define        PvmNoSuchBuf    -16     /* No such buffer */
+#define        PvmNullGroup    -17     /* Null group name */
+#define        PvmDupGroup             -18     /* Already in group */
+#define        PvmNoGroup              -19     /* No such group */
+#define        PvmNotInGroup   -20     /* Not in group */
+#define        PvmNoInst               -21     /* No such instance */
+#define        PvmHostFail             -22     /* Host failed */
+#define        PvmNoParent             -23     /* No parent task */
+#define        PvmNotImpl              -24     /* Not implemented */
+#define        PvmDSysErr              -25     /* Pvmd system error */
+#define        PvmBadVersion   -26     /* Version mismatch */
+#define        PvmOutOfRes             -27     /* Out of resources */
+#define        PvmDupHost              -28     /* Duplicate host */
+#define        PvmCantStart    -29     /* Can't start pvmd */
+#define        PvmAlready              -30     /* Already in progress */
+#define        PvmNoTask               -31     /* No such task */
+#define        PvmNoEntry              -32     /* No such entry */
+#define        PvmDupEntry             -33     /* Duplicate entry */
+
+/*
+*      Data types for pvm_reduce(), pvm_psend(), pvm_precv()
+*/
+
+#define        PVM_STR                 0       /* string */
+#define        PVM_BYTE                1       /* byte */
+#define        PVM_SHORT               2       /* short */
+#define        PVM_INT                 3       /* int */
+#define        PVM_FLOAT               4       /* real */
+#define        PVM_CPLX                5       /* complex */
+#define        PVM_DOUBLE              6       /* double */
+#define        PVM_DCPLX               7       /* double complex */
+#define        PVM_LONG                8       /* long integer */
+#define        PVM_USHORT              9       /* unsigned short int */
+#define        PVM_UINT                10      /* unsigned int */
+#define        PVM_ULONG               11      /* unsigned long int */
+
+#endif
diff --git a/src/langs/pvmc/pvmc.h b/src/langs/pvmc/pvmc.h
new file mode 100644 (file)
index 0000000..6bddaee
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __PVMC_H__
+#define __PVMC_H__
+
+#include "converse.h"
+#include "pvm3.h"
+
+#define PRINTF         CmiPrintf
+#define MALLOC(x)      CmiAlloc(x)
+#define FREE(x)                CmiFree(x)
+#define MYPE()         CmiMyPe()
+#define NUMPES()       CmiMyPe()
+#define TID2PE(x)       ((x)-1)
+#define PE2TID(x)       ((x)+1)
+
+#define PVMC_CTRL_AT_BARRIER           1
+#define PVMC_CTRL_THROUGH_BARRIER      2
+#define PVMC_CTRL_KILL                 3
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+
+#ifndef TRUE
+#define TRUE   1
+#endif
+
+#endif
diff --git a/src/langs/pvmc/pvmc_buf.c b/src/langs/pvmc/pvmc_buf.c
new file mode 100644 (file)
index 0000000..964b3c9
--- /dev/null
@@ -0,0 +1,629 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <converse.h>
+#include "pvmc.h"
+
+#define MAX_BUFFERS 1000
+
+typedef struct pvmc_item_s {
+  int type;
+  int size;
+  int free_data;
+  char *data;
+  struct pvmc_item_s *nxt;
+} pvmc_item;
+
+typedef struct pvmc_buffer_s {
+  int bufid;
+  int bytes;
+  int tag;
+  int tid;
+  int num_items;
+  int refcount;
+  pvmc_item *first_item;
+  pvmc_item *cur_item;
+  pvmc_item *last_item;
+  struct pvmc_buffer_s *nxt_free;
+  char *data_buf;
+} pvmc_buffer;
+
+CpvStaticDeclare(pvmc_buffer*,pvmc_bufarray);
+CpvStaticDeclare(pvmc_buffer*,pvmc_freebufs);
+CpvStaticDeclare(int,pvmc_sbufid);
+CpvStaticDeclare(int,pvmc_rbufid);
+
+void pvmc_init_bufs(void)
+{
+  int i;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:%s:%d pvmc_init_bufs() initializing buffer array\n",
+       MYPE(),pvm_mytid(),__FILE__,__LINE__);
+#endif
+
+  CpvInitialize(pvmc_buffer*,pvmc_bufarray);
+  CpvAccess(pvmc_bufarray)=MALLOC(sizeof(pvmc_buffer)*MAX_BUFFERS);
+  if (CpvAccess(pvmc_bufarray)==NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_init_bufs() can't alloc buffer array\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    exit(1);
+  }
+    
+  CpvInitialize(pvmc_buffer*,pvmc_freebufs);
+  CpvAccess(pvmc_freebufs)=&(CpvAccess(pvmc_bufarray)[1]);  /* throw away first bufid */
+  
+  for(i=0;i<MAX_BUFFERS;i++) {
+    CpvAccess(pvmc_bufarray)[i].bufid=i;
+    CpvAccess(pvmc_bufarray)[i].bytes=0;
+    CpvAccess(pvmc_bufarray)[i].tag=0;
+    CpvAccess(pvmc_bufarray)[i].tid=-1;
+    CpvAccess(pvmc_bufarray)[i].num_items=-1;
+    CpvAccess(pvmc_bufarray)[i].refcount=0;
+    CpvAccess(pvmc_bufarray)[i].first_item=(pvmc_item *)NULL;
+    CpvAccess(pvmc_bufarray)[i].cur_item=(pvmc_item *)NULL;
+    CpvAccess(pvmc_bufarray)[i].last_item=(pvmc_item *)NULL;
+    if (i==MAX_BUFFERS-1)
+      CpvAccess(pvmc_bufarray)[i].nxt_free=(pvmc_buffer *)NULL;
+    else
+      CpvAccess(pvmc_bufarray)[i].nxt_free=&(CpvAccess(pvmc_bufarray)[i+1]);
+
+    CpvAccess(pvmc_bufarray)[i].data_buf=(char *)NULL;
+  }
+
+  CpvInitialize(int,pvmc_sbufid);
+  CpvAccess(pvmc_sbufid) = 0;
+
+  CpvInitialize(int,pvmc_rbufid);
+  CpvAccess(pvmc_rbufid) = 0;
+}
+
+int pvm_mkbuf(int encoding)
+{
+  pvmc_buffer *new_buf;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_mkbuf(%d)\n",
+       MYPE(),pvm_mytid(),encoding);
+
+  if (encoding != PvmDataRaw)
+    PRINTF("Pe(%d) tid=%d:%s:%d Warning: only encoding=PvmDataRaw supported\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+#endif
+
+  new_buf = CpvAccess(pvmc_freebufs);
+  if (new_buf == NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_mkbuf() no more buffers\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  }
+
+  CpvAccess(pvmc_freebufs)=CpvAccess(pvmc_freebufs)->nxt_free;
+  new_buf->bytes=0;
+  new_buf->tag=0;
+  new_buf->tid=pvm_mytid();
+  new_buf->num_items = 0;
+  if ((new_buf->first_item=
+       (pvmc_item *)MALLOC(sizeof(pvmc_item))) == NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_mkbuf() MALLOC failed\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  }
+  new_buf->first_item->type=0;
+  new_buf->first_item->size=0;
+  new_buf->first_item->free_data=FALSE;
+  new_buf->first_item->data=(char *)NULL;
+  new_buf->first_item->nxt=(pvmc_item *)NULL;
+
+  new_buf->cur_item=new_buf->first_item;
+  new_buf->last_item=new_buf->first_item;
+  new_buf->refcount=1;
+  return new_buf->bufid;
+}
+  
+static void pvmc_emptybuf(pvmc_buffer *cur_buf)
+{
+  pvmc_item *nxt_item, *prv_item; 
+
+  if (cur_buf->data_buf) {
+    FREE(cur_buf->data_buf);
+    cur_buf->data_buf=(char *)NULL;
+  }
+
+  nxt_item=cur_buf->first_item;
+  while (nxt_item) {
+    prv_item=nxt_item;
+    nxt_item=nxt_item->nxt;
+    if (prv_item->free_data)
+      FREE(prv_item->data);
+    FREE(prv_item);
+  }
+  cur_buf->bytes=0;
+  cur_buf->tag=0;
+  cur_buf->tid=-1;
+  cur_buf->num_items=0;
+  cur_buf->first_item=(pvmc_item *)NULL;
+  cur_buf->cur_item=(pvmc_item *)NULL;
+  cur_buf->last_item=(pvmc_item *)NULL;
+}
+
+int pvm_freebuf(int bufid)
+{
+  pvmc_buffer *cur_buf;
+  int result=0;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_freebuf(%d)\n",MYPE(),pvm_mytid(),bufid);
+#endif
+
+  if ((bufid<=0) || (bufid>=MAX_BUFFERS)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_freebuf() attempted to free out of range bufid\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  }
+    
+  cur_buf = &(CpvAccess(pvmc_bufarray)[bufid]);
+
+  if (cur_buf->refcount < 1) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_freebuf(%d) refcount=%d, i'm confused\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__,bufid,cur_buf->refcount);
+    result=-2;
+  }
+  cur_buf->refcount--;
+
+  if (cur_buf->refcount==0) {
+    pvmc_emptybuf(cur_buf);
+    cur_buf->nxt_free=CpvAccess(pvmc_freebufs);
+    CpvAccess(pvmc_freebufs)=cur_buf;
+  }
+
+  #ifdef PVM_DEBUG
+  {
+    int x;
+    int Counter=0;
+    int FreeCounter=0;
+    struct pvmc_buffer_s *FreeList;
+    /* find the number that we think are free */
+    for(x=0; x<MAX_BUFFERS; x++)
+    {
+      if (CpvAccess(pvmc_bufarray)[x].refcount == 0) Counter++;
+    }
+    /* find the number that are linked as free */
+    FreeList = CpvAccess(pvmc_freebufs);
+    while(FreeList != NULL)
+    {
+      FreeCounter++;
+      FreeList = FreeList->nxt_free;
+    }
+    /* show the results */
+    PRINTF("Pe(%d) tid=%d:%s:%d unused=(%d) sizeof(freelist)=%d\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__,Counter,FreeCounter);
+  }
+  #endif
+
+  return result;
+}  
+
+static int pvmc_getbuf(int bufid)
+{
+  pvmc_buffer *cur_buf;
+
+  if ((bufid<=0) || (bufid>=MAX_BUFFERS)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getbuf(%d) attempted to get out of range bufid\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__,bufid);
+    return -1;
+  }
+    
+  cur_buf = &(CpvAccess(pvmc_bufarray)[bufid]);
+
+  if (cur_buf->refcount<1) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_getbuf() trying with refcount=%d, i'm confused\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__,cur_buf->refcount);
+    return -1;
+  }
+
+  cur_buf->refcount++;
+  return bufid;
+}
+
+int pvm_getsbuf(void)
+{
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_getsbuf()\n",MYPE(),pvm_mytid());
+#endif
+  return CpvAccess(pvmc_sbufid);
+}
+
+int pvm_setsbuf(int bufid)
+{
+  int prv_sbufid;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_setsbuf(%d)\n",MYPE(),pvm_mytid(),bufid);
+#endif
+
+  prv_sbufid=CpvAccess(pvmc_sbufid);
+
+  /*
+  if (prv_sbufid>0) {
+    pvmc_getbuf(prv_sbufid);
+    pvm_freebuf(prv_sbufid);
+  }
+  */
+
+  CpvAccess(pvmc_sbufid)=bufid;
+
+  return prv_sbufid;
+}
+
+int pvm_getrbuf(void)
+{
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_getrbuf()\n",MYPE(),pvm_mytid());
+#endif
+  return CpvAccess(pvmc_rbufid);
+}
+
+int pvm_setrbuf(int bufid)
+{
+  int prv_rbufid;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_setrbuf(%d)\n",MYPE(),pvm_mytid(),bufid);
+#endif
+  prv_rbufid=CpvAccess(pvmc_rbufid);
+
+  /*
+  if (prv_rbufid>0) {
+    pvmc_getbuf(prv_rbufid);
+    pvm_freebuf(prv_rbufid);
+  }
+  */
+    
+
+  CpvAccess(pvmc_rbufid)=bufid;
+
+  return prv_rbufid;
+}
+
+int pvm_initsend(int encoding)
+{
+  int newbufid;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_initsend(%d)\n",MYPE(),pvm_mytid(),encoding);
+#endif
+  if (CpvAccess(pvmc_sbufid) > 0)
+    pvm_freebuf(CpvAccess(pvmc_sbufid));
+
+  newbufid=pvm_mkbuf(encoding);
+
+  if (newbufid<=0) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_initsend() couldn't alloc new buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+  }
+  CpvAccess(pvmc_sbufid)=newbufid;
+  return CpvAccess(pvmc_sbufid);
+}
+
+int pvm_bufinfo(int bufid, int *bytes, int *msgtag, int *tid)
+{
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_bufinfo(%d,0x%x,0x%x,0x%x)\n",
+        pvm_mytid(),bufid,bytes,msgtag,tid);
+#endif
+
+  if ((bufid<=0) || (bufid >= MAX_BUFFERS) ||
+      (CpvAccess(pvmc_bufarray)[bufid].refcount <= 0)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_bufinfo(%d) info requested about unused buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__,bufid);
+    return -1;
+  }
+  if (bytes)
+    *bytes=CpvAccess(pvmc_bufarray)[bufid].bytes;
+  if (msgtag)
+    *msgtag=CpvAccess(pvmc_bufarray)[bufid].tag;
+  if (tid)
+    *tid=CpvAccess(pvmc_bufarray)[bufid].tid;
+  return 0;
+}
+
+int pvmc_sendmsgsz(void)
+{
+  int msgsz;
+  pvmc_buffer *cur_buf;
+  pvmc_item *cur_item;
+
+  if ((CpvAccess(pvmc_sbufid)<=0) || (CpvAccess(pvmc_sbufid) >= MAX_BUFFERS) ||
+      (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)].refcount <= 0)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_sendmsgsz() size requested for unused send buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  }
+
+  cur_buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)]);
+
+  msgsz=sizeof(cur_buf->bytes)+sizeof(cur_buf->tag)+
+    sizeof(cur_buf->tid)+sizeof(cur_buf->num_items);
+
+  cur_item=cur_buf->first_item;
+  while (cur_item != cur_buf->last_item) {
+    msgsz += cur_item->size+sizeof(cur_item->type)+sizeof(cur_item->size);
+    cur_item = cur_item->nxt;
+  }
+
+  return msgsz;
+}
+
+int pvmc_settidtag(int pvm_tid, int tag)
+{
+  pvmc_buffer *cur_buf;
+
+  if ((CpvAccess(pvmc_sbufid)<=0) || (CpvAccess(pvmc_sbufid) >= MAX_BUFFERS) ||
+      (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)].refcount <= 0)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_setidtag() unused send buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  }
+  cur_buf=&(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)]);
+  cur_buf->tag = tag;
+  cur_buf->tid = pvm_tid;
+}
+
+
+int pvmc_packmsg(void *msgbuf)
+{
+  pvmc_buffer *cur_buf;
+  pvmc_item *cur_item;
+  int bytes_packed=0;
+
+  if ((CpvAccess(pvmc_sbufid)<=0) || (CpvAccess(pvmc_sbufid) >= MAX_BUFFERS) ||
+      (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)].refcount <= 0)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_packmsg() unused send buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  }
+  cur_buf=&(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)]);
+  *((int *)((char *)msgbuf+bytes_packed)) = cur_buf->bytes;
+  bytes_packed+=sizeof(int);
+  *((int *)((char *)msgbuf+bytes_packed)) = cur_buf->tag;
+  bytes_packed+=sizeof(int);
+  *((int *)((char *)msgbuf+bytes_packed)) = cur_buf->tid;
+  bytes_packed+=sizeof(int);
+  *((int *)((char *)msgbuf+bytes_packed)) = cur_buf->num_items;
+  bytes_packed+=sizeof(int);
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) pvmc_packmsg: %d items packed for tag %d\n",
+        MYPE(),cur_buf->num_items,cur_buf->tag);
+#endif
+  cur_item=cur_buf->first_item;
+  while(cur_item!=cur_buf->last_item) {
+    *((int *)((char *)msgbuf+bytes_packed)) = cur_item->type;
+    bytes_packed+=sizeof(int);
+    *((int *)((char *)msgbuf+bytes_packed)) = cur_item->size;
+    bytes_packed+=sizeof(int);
+    cur_item=cur_item->nxt;
+  }
+    
+  cur_item=cur_buf->first_item;
+  while(cur_item!=cur_buf->last_item) {
+    if (cur_item->size > 0) {
+      memcpy((void *)((char *)msgbuf+bytes_packed),cur_item->data,
+            cur_item->size);
+      bytes_packed+=cur_item->size;
+    }
+    cur_item=cur_item->nxt;
+  }
+  return bytes_packed;
+}
+
+int pvmc_unpackmsg(void *msgbuf, void *start_of_msg)
+{
+  pvmc_buffer *cur_buf;
+  pvmc_item *cur_item, *nxt_item;
+  int bytes_unpacked=0;
+  int i;
+
+  if ((CpvAccess(pvmc_rbufid)<=0) || (CpvAccess(pvmc_rbufid) >= MAX_BUFFERS) ||
+      (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)].refcount <= 0)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_unpackmsg() uninitialized recv buffer\n",
+          MYPE(),__FILE__,__LINE__);
+    return -1;
+  }
+  cur_buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)]);
+  pvmc_emptybuf(cur_buf);
+
+  cur_buf->bytes = *((int *)((char *)start_of_msg+bytes_unpacked));
+  bytes_unpacked += sizeof(int);
+  cur_buf->tag = *((int *)((char *)start_of_msg+bytes_unpacked));
+  bytes_unpacked += sizeof(int);
+  cur_buf->tid = *((int *)((char *)start_of_msg+bytes_unpacked));
+  bytes_unpacked += sizeof(int);
+  cur_buf->num_items = *((int *)((char *)start_of_msg+bytes_unpacked));
+  bytes_unpacked += sizeof(int);
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) pvmc_unpackmsg: %d items unpacked for tag %d\n",
+        MYPE(),cur_buf->num_items,cur_buf->tag);
+#endif
+  if (msgbuf)
+    cur_buf->data_buf = msgbuf;
+  else cur_buf->data_buf = (void *)NULL;
+
+  cur_item=(pvmc_item *)MALLOC(sizeof(pvmc_item));
+  cur_buf->first_item=cur_item;
+  cur_buf->cur_item=cur_item;
+
+  if (cur_item==(pvmc_item *)NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_unpackmsg() can't allocate memory\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  }
+
+#if PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:%s:%d pvmc_unpackmsg() unpacking %d messages.\n",
+       MYPE(),pvm_mytid(),__FILE__,__LINE__,cur_buf->num_items);
+#endif
+
+  for(i=0;i<cur_buf->num_items;i++) {
+    cur_item->type = *((int *)((char *)start_of_msg+bytes_unpacked));
+    bytes_unpacked+=sizeof(int);
+    cur_item->size = *((int *)((char *)start_of_msg+bytes_unpacked));
+    bytes_unpacked+=sizeof(int);
+    
+    nxt_item=(pvmc_item *)MALLOC(sizeof(pvmc_item));
+
+    if (!nxt_item) {
+      PRINTF("Pe(%d) tid=%d:%s:%d pvmc_unpackmsg() can't allocate memory\n",
+            MYPE(),pvm_mytid(),__FILE__,__LINE__);
+      return -1;
+    }
+    cur_item->nxt = nxt_item;
+    cur_item = nxt_item;
+  }
+  
+  cur_item->type = 0;
+  cur_item->size = 0;
+  cur_item->free_data = FALSE;
+  cur_item->data = (char *) NULL;
+  cur_item->nxt = (pvmc_item *) NULL;
+
+  cur_buf->last_item = cur_item;
+    
+  cur_item = cur_buf->first_item;
+  while(cur_item!=cur_buf->last_item) {
+    if (cur_item->size > 0) {
+      cur_item->free_data=FALSE;
+      cur_item->data = (void *)((char *)start_of_msg+bytes_unpacked);
+      bytes_unpacked+=cur_item->size;
+    }
+    else cur_item->data=NULL;
+    cur_item = cur_item->nxt;
+  }
+
+  return bytes_unpacked;
+}
+
+int pvmc_gettag(void *msgbuf)
+{
+  return *((int *)msgbuf+1);
+}
+
+void *pvmc_mkitem(int nbytes, int type)
+{
+  pvmc_buffer *buf;
+  void *databuf;
+
+  if ((CpvAccess(pvmc_sbufid)<=0) || (CpvAccess(pvmc_sbufid) >= MAX_BUFFERS) ||
+      (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)].refcount <= 0)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_mkitem() unused send buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return NULL;
+  }
+  buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_sbufid)]);
+
+  buf->last_item->type=type;
+  buf->last_item->size=nbytes;
+  databuf=MALLOC(nbytes);
+  if (!databuf) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_mkitem() can't allocate data space\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return databuf;
+  }
+  buf->last_item->free_data=TRUE;
+  buf->last_item->data=databuf;
+  buf->last_item->nxt=(pvmc_item *)MALLOC(sizeof(pvmc_item));
+  if (buf->last_item->nxt==NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_mkitem() can't allocate new item\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return NULL;
+  }
+
+  buf->last_item=buf->last_item->nxt;
+  buf->last_item->type=0;
+  buf->last_item->size=0;
+  buf->last_item->free_data=FALSE;
+  buf->last_item->data=(char *)NULL;
+  buf->last_item->nxt=(pvmc_item *)NULL;
+  buf->num_items++;
+
+  return databuf;
+}
+
+void *pvmc_getitem(int n_bytes, int type)
+{
+  pvmc_buffer *buf;
+  pvmc_item *item;
+  void *data;
+
+  if ((CpvAccess(pvmc_rbufid)<=0) || (CpvAccess(pvmc_rbufid) >= MAX_BUFFERS) ||
+      (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)].refcount <= 0)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() uninitialized recv buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return NULL;
+  }
+  buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)]);
+
+  item = buf->cur_item;
+
+  if (item==buf->last_item) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() no more items\n",
+         MYPE(),pvm_mytid(), __FILE__,__LINE__);
+    data=NULL;
+  } else if (item->data==(void *)NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() uninitialized data\n",
+         MYPE(),pvm_mytid(), __FILE__,__LINE__);
+    data=NULL;
+  } else if (item->size < n_bytes) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() data size mismatch\n",
+         MYPE(),pvm_mytid(), __FILE__,__LINE__);
+    data=NULL;
+  } else if (item->type != type) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getitem() type mismatch\n",
+         MYPE(),pvm_mytid(), __FILE__,__LINE__);
+    data=NULL;
+  } else {
+    data=item->data;
+  }
+
+  buf->cur_item = buf->cur_item->nxt;
+  return data;
+}
+
+void *pvmc_getstritem(int *n_bytes)
+{
+  pvmc_buffer *buf;
+  pvmc_item *item;
+  void *data;
+
+  if ((CpvAccess(pvmc_rbufid)<=0) || (CpvAccess(pvmc_rbufid) >= MAX_BUFFERS) ||
+      (CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)].refcount <= 0)) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getstritem() uninitialized recv buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return NULL;
+  }
+  buf = &(CpvAccess(pvmc_bufarray)[CpvAccess(pvmc_rbufid)]);
+
+  item = buf->cur_item;
+  *n_bytes = item->size;
+
+  if (item==buf->last_item) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getstritem() no more items\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    data=NULL;
+  } else if (item->data==(void *)NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getstritem() uninitialized data\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    data=NULL;
+  } else if (item->type != PVM_STR) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_getstritem() type mismatch\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    data=NULL;
+  } else {
+    data=item->data;
+  }
+
+  buf->cur_item = buf->cur_item->nxt;
+  return data;
+}
+
diff --git a/src/langs/pvmc/pvmc_comm.c b/src/langs/pvmc/pvmc_comm.c
new file mode 100644 (file)
index 0000000..78d6496
--- /dev/null
@@ -0,0 +1,329 @@
+#include <stddef.h>
+#include "converse.h"
+#include "pvmc.h"
+
+CpvStaticDeclare(CmmTable,seq_table);
+
+CpvStaticDeclare(int,pvmc_control_handler);
+CpvStaticDeclare(int,pvmc_msg_handler);
+CpvStaticDeclare(int*,send_seq_num);
+CpvStaticDeclare(int*,recv_seq_num);
+
+CpvExtern(int,pvmc_barrier_num);
+CpvExtern(int,pvmc_at_barrier_num);
+
+typedef struct msg_hdr_struct {
+  char handler[CmiMsgHeaderSizeBytes];
+  int sender;
+  unsigned int seq_num;
+} msg_hdr;
+
+typedef struct control_msg_struct {
+  char handler[CmiMsgHeaderSizeBytes];
+  int type;
+} control_msg;
+
+static void pvmc_control_handler_func();
+static void pvmc_msg_handler_func();
+
+void pvmc_init_comm(void)
+{
+  int i;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_init_comm()\n",MYPE(),pvm_mytid());
+#endif
+
+  CpvInitialize(CmmTable,seq_table);
+  CpvAccess(seq_table) = CmmNew();
+
+  CpvInitialize(int,pvmc_control_handler);
+  CpvAccess(pvmc_control_handler)=
+    CmiRegisterHandler(pvmc_control_handler_func);
+  
+  CpvInitialize(int,pvmc_msg_handler);
+  CpvAccess(pvmc_msg_handler)=CmiRegisterHandler(pvmc_msg_handler_func);
+
+  CpvInitialize(int*,recv_seq_num);
+  CpvAccess(recv_seq_num)=MALLOC(CmiNumPes()*sizeof(int));
+
+  if (CpvAccess(recv_seq_num)==NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_init_comm() can't allocate seq buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    exit();
+  }
+  for(i=0; i<CmiNumPes(); i++)
+    CpvAccess(recv_seq_num)=0;
+
+  CpvInitialize(int*,send_seq_num);
+  CpvAccess(send_seq_num)=MALLOC(CmiNumPes()*sizeof(int));
+
+  if (CpvAccess(send_seq_num)==NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvmc_init_comm() can't allocate seq buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    exit();
+  }
+  for(i=0; i<CmiNumPes(); i++)
+    CpvAccess(send_seq_num)[i]=0;
+
+}
+
+void pvmc_send_control_msg(int type, int pe)
+{
+  control_msg *msg;
+
+  msg=CmiAlloc(sizeof(control_msg));
+  msg->type=type;
+  CmiSetHandler(msg,CpvAccess(pvmc_control_handler));
+  CmiSyncSendAndFree(pe,sizeof(control_msg),msg);
+}
+
+static void pvmc_control_handler_func(control_msg *msg)
+{
+  switch (msg->type)  {
+  case PVMC_CTRL_AT_BARRIER:
+    CpvAccess(pvmc_at_barrier_num)++;
+    break;
+  case PVMC_CTRL_THROUGH_BARRIER:
+    CpvAccess(pvmc_barrier_num)++;
+    break;
+  case PVMC_CTRL_KILL:
+    ConverseExit();
+    exit();
+    break;
+  default:
+    PRINTF("WARNING: %s:%d, Illegal control message\n",__FILE__,__LINE__);
+  }
+}
+
+static void pvmc_msg_handler_func(void *msg)
+{
+  int seq_num;
+  int sender;
+  int pvm_tag;
+  int tags[2];
+  int rtags[2];
+
+  CmiGrabBuffer(&msg);
+
+  sender=((msg_hdr *)msg)->sender;
+  seq_num=((msg_hdr *)msg)->seq_num;
+  
+  tags[0]=sender;
+  tags[1]=pvmc_gettag((char *)msg+sizeof(msg_hdr));
+  CmmPut(CpvAccess(seq_table),2,tags,msg);
+}
+
+int pvm_kill(int tid)
+{
+  control_msg *exit_msg;
+  
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_kill(%d)\n",
+       MYPE(),pvm_mytid(),tid);
+#endif
+  pvmc_send_control_msg(PVMC_CTRL_KILL,TID2PE(tid));
+}
+
+int pvm_send(int pvm_tid, int tag)
+{
+  void *msg;
+  int msg_sz, conv_tid, conv_tag;
+  
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_send(%d,%d)\n",
+       MYPE(),pvm_mytid(),pvm_tid,tag);
+#endif
+  pvmc_settidtag(pvm_mytid(),tag);
+
+  if ((pvm_tid<1) || ( pvm_tid > CmiNumPes())) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_send() illegal tid %d\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__,pvm_tid);
+    return -1;
+  } else conv_tid = pvm_tid-1;
+
+  if (tag<0) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_send() illegal tag\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  } else conv_tag = tag;
+
+  msg_sz = sizeof(msg_hdr)+pvmc_sendmsgsz();
+  msg = CmiAlloc(msg_sz);
+
+  if (msg==NULL) {
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_send() can't alloc msg buffer\n",
+          MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    return -1;
+  }
+
+  CmiSetHandler(msg,CpvAccess(pvmc_msg_handler));
+  ((msg_hdr *)msg)->sender=MYPE();
+  ((msg_hdr *)msg)->seq_num=CpvAccess(send_seq_num)[conv_tid];
+  CpvAccess(send_seq_num)[conv_tid]++;
+  
+  pvmc_packmsg((char *)msg + (int)sizeof(msg_hdr));
+  CmiSyncSendAndFree(conv_tid,msg_sz,msg);
+  return 0;
+}
+
+int pvm_mcast(int *tids, int ntask, int msgtag)
+{
+  int i;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_mcast(%x,%d,%d)\n",
+       MYPE(),pvm_mytid(),tids,ntask,msgtag);
+#endif
+  for(i=0;i<ntask;i++)
+    pvm_send(tids[i],msgtag);
+}
+
+int pvm_nrecv(int tid, int tag)
+{
+  int conv_tid, conv_tag;
+  void *msg;
+  int tags[2];
+  int rtags[2];
+  int sender, seq_num;
+  int rbuf;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_nrecv(%d,%d)\n",
+       MYPE(),pvm_mytid(),tid,tag);
+#endif
+
+  if (tid==-1)
+    conv_tid=CmmWildCard;
+  else conv_tid=tid-1;
+
+  if (tag==-1)
+    conv_tag=CmmWildCard;
+  else conv_tag=tag;
+
+  /*
+   * Empty messages from machine layer.
+   */
+
+  while(CmiDeliverMsgs(1)==0)
+    ;
+
+  /*
+   *  See if the message is already in the tag table and extract it.
+   */
+  
+  tags[0]=conv_tid;
+  tags[1]=conv_tag;
+  msg=CmmGet(CpvAccess(seq_table),2,tags,rtags);
+  if (msg!=NULL) {
+    sender = rtags[0];
+    /*
+    seq_num = CpvAccess(recv_seq_num)[sender];
+
+    if ((((msg_hdr *)msg)->seq_num) != seq_num)
+      PRINTF("tid=%d:%s:%d pvm_recv() seq number mismatch, I'm confused\n",
+            tid,__FILE__,__LINE__);
+    else CpvAccess(recv_seq_num)[sender]++;
+    */
+
+
+    rbuf=pvm_setrbuf(pvm_mkbuf(PvmDataRaw));
+    if (rbuf > 0)
+      {
+#ifdef PVM_DEBUG
+      PRINTF("Pe(%d) tid=%d:%s:%d pvm_nrecv() says pvm_setrbuf=%d\n",
+       MYPE(),tid,__FILE__,__LINE__,rbuf);
+#endif
+      pvm_freebuf(rbuf);
+      }
+    pvmc_unpackmsg(msg,(char *)msg+sizeof(msg_hdr));
+
+#ifdef PVM_DEBUG
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_nrecv() returning pvm_getrbuf()=%d\n",
+       MYPE(),tid,__FILE__,__LINE__,pvm_getrbuf());
+#endif
+    return pvm_getrbuf();
+  }
+  else return 0;  /* Non blocking receive returns immediately. */
+}
+
+int pvm_recv(int tid, int tag)
+{
+  int bufid=0;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_recv(%d,%d)\n",
+       MYPE(),pvm_mytid(),tid,tag);
+#endif
+  while (bufid==0)
+    bufid=pvm_nrecv(tid,tag);
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_recv(%d,%d) returning %d\n",
+       MYPE(),pvm_mytid(),tid,tag,bufid);
+#endif
+
+  return bufid;
+}
+
+int pvm_probe(int tid, int tag)
+{
+  int conv_tid, conv_tag;
+  void *msg;
+  int tags[2];
+  int rtags[2];
+  int sender, seq_num;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_probe(%d,%d)\n",
+       MYPE(),pvm_mytid(),tid,tag);
+#endif
+  if (tid==-1)
+    conv_tid=CmmWildCard;
+  else conv_tid=tid;
+
+  if (tag==-1)
+    conv_tag=CmmWildCard;
+  else conv_tag=tag;
+
+  /*
+   * Empty messages from machine layer.
+   */
+
+  while(CmiDeliverMsgs(1)==0)
+    ;
+
+  /*
+   *  See if the message is already in the tag table
+   */
+  
+  tags[0]=conv_tid;
+  tags[1]=conv_tag;
+  msg=CmmProbe(CpvAccess(seq_table),2,tags,rtags);
+  if (msg!=NULL) {
+    /*
+    sender = rtag[0];
+    seq_num = CpvAccess(recv_seq_num)[sender];
+
+    if ((((msg_hdr *)msg)->seq_num) != seq_num)
+      PRINTF("Pe(%d) tid=%d:%s:%d pvm_recv() seq num mismatch, I'm confused\n",
+             MYPE(),pvm_mytid(),__FILE__,__LINE__);
+    else CpvAccess(recv_seq_num)[sender]++;
+    */
+
+  /*
+   * We will just unpack the message, so bufinfo works, but this
+   * should really just set up what bufinfo needs and unpack the
+   * rest later
+   */
+    pvmc_unpackmsg(msg,(char *)msg+sizeof(msg_hdr));
+
+
+#ifdef PVM_DEBUG
+    PRINTF("Pe(%d) tid=%d:%s:%d pvm_probe() returning pvm_getrbuf()=%d\n",
+       MYPE(),tid,__FILE__,__LINE__,pvm_getrbuf());
+#endif
+    return pvm_getrbuf();
+  }
+  else return 0;  /* Probe returns immediately. */
+}
diff --git a/src/langs/pvmc/pvmc_conv.c b/src/langs/pvmc/pvmc_conv.c
new file mode 100644 (file)
index 0000000..158c314
--- /dev/null
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <stddef.h>
+#include <converse.h>
+#include "pvmc.h"
+
+void pvmc_init(void)
+{
+  pvmc_init_bufs();
+  pvmc_init_comm();
+  pvmc_init_groups();
+}
+
+int pvm_mytid(void)
+{
+  /*
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_mytid()\n",MYPE(),PE2TID(MYPE()+1));
+#endif
+*/
+  return PE2TID(MYPE());
+}
+
+int pvm_exit(void)
+{
+  int sleepval;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_exit()\n",MYPE(),pvm_mytid());
+#endif
+
+  ConverseExit();
+}
+
+int pvm_spawn(char *task, char **argv, int flag,
+             char *where, int ntask, int *tids)
+{
+  int i;
+  int numt;
+
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_spawn()\n",MYPE(),pvm_mytid());
+#endif
+
+  numt = ntask;
+  if (numt > CmiNumPes())
+    numt = CmiNumPes();
+#ifdef PVM_DEBUG
+  PRINTF("%s: preping %d tids (wanted to prep %d)\n",__FILE__,numt,ntask);
+#endif
+  for(i=0; i<numt; i++)
+  {
+    tids[i]=PE2TID(i);
+#ifdef PVM_DEBUG
+    PRINTF("Pe(%d) tids[%d]=%d  (%d)\n",MYPE(),i,PE2TID(i),tids[i]);
+#endif
+  }
+    
+  return numt;
+}
+
+int pvm_parent(void)
+{
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_parent()\n",MYPE(),pvm_mytid());
+#endif
+
+  /*  
+   *  I think it would be better to return PvmNoParent, but
+   *  this may make sense too, and it makes namd2/DPMTA work.
+   */
+  return 1;
+}
+
+int pvm_config(int *nhost, int *narch, struct pvmhostinfo **hostp)
+{
+  int i, nh;
+
+#ifdef PVM_DEBUG
+  PRINTF("tid=%d:pvm_config(%x,%x,%x)\n",pvm_mytid(),nhost,narch,hostp);
+#endif
+
+  printf("tid=%d:pvm_config(%x,%x,%x)\n",pvm_mytid(),nhost,narch,hostp);
+  printf("%d\n",*nhost);
+  /*  sleep(10); */
+  
+  if (nhost)
+    *nhost=nh=CmiNumPes();
+  if (narch)
+    *narch=1;
+
+  *hostp = (struct pvmhostinfo *)MALLOC(nh*sizeof(struct pvmhostinfo));
+
+  if (*hostp == (struct pvmhostinfo *)NULL)
+    return -1;
+
+  for(i=0; i<nh; i++) {
+    hostp[i]->hi_tid=PE2TID(i);
+    hostp[i]->hi_name="";
+    hostp[i]->hi_arch="CONVERSE";
+    hostp[i]->hi_speed=1000;
+  }
+
+  return 0;
+}
+
+int pvm_tasks(int which, int *ntask, struct pvmtaskinfo **taskp)
+{
+  int i;
+
+#ifdef PVM_DEBUG
+  PRINTF("tid=%d:pvm_tasks(%d,%x,%x)\n",pvm_mytid(),which,ntask,taskp);
+#endif
+
+  if (which==0)
+    *ntask=CmiNumPes();
+  else
+    *ntask=1;
+
+  *taskp = (struct pvmtaskinfo *)MALLOC(*ntask * sizeof(struct pvmtaskinfo));
+  
+  if (*taskp == (struct pvmtaskinfo *)NULL)
+    return -1;
+
+  for(i=0; i<*ntask; i++) {
+    taskp[i]->ti_tid=PE2TID(i);
+    taskp[i]->ti_ptid=PE2TID(0);
+    taskp[i]->ti_host=PE2TID(i);
+    taskp[i]->ti_flag=0;
+    taskp[i]->ti_a_out="";
+  }     
+
+  return 0;
+}
+
+int pvm_setopt(int what, int val)
+{
+#ifdef PVM_DEBUG
+  PRINTF("tid=%d:pvm_setopt(%d,%d)\n",pvm_mytid(),what,val);
+#endif
+  return val;
+}
+
+int pvm_gsize(char *group)
+{
+#ifdef PVM_DEBUG
+  PRINTF("tid=%d:pvm_gsize(%s)\n",pvm_mytid(),group);
+#endif
+  return CmiNumPes();
+}
+
+int pvm_gettid(char *group, int inum)
+{
+#ifdef PVM_DEBUG
+  PRINTF("tid=%d:pvm_gettid(%s,%d)\n",pvm_mytid(),group,inum);
+#endif
+  return inum;
+}
+
+int pvm_catchout(FILE *ff)
+{
+  PRINTF("Warning: pvm_catchout not implemented\n");
+}
diff --git a/src/langs/pvmc/pvmc_groups.c b/src/langs/pvmc/pvmc_groups.c
new file mode 100644 (file)
index 0000000..3b8d0f8
--- /dev/null
@@ -0,0 +1,110 @@
+#include <stddef.h>
+#include <converse.h>
+#include "pvmc.h"
+
+CpvDeclare(int,pvmc_at_barrier_num);
+CpvDeclare(int,pvmc_barrier_num);
+CpvStaticDeclare(int,pvmc_last_at_barrier_num);
+CpvStaticDeclare(int,pvmc_last_barrier_num);
+
+CpvExtern(int,pvmc_control_handler);
+
+void pvmc_init_groups()
+{
+  CpvInitialize(int,pvmc_barrier_num);
+  CpvAccess(pvmc_barrier_num)=0;
+  CpvInitialize(int,pvmc_at_barrier_num);
+  CpvAccess(pvmc_at_barrier_num)=0;
+  CpvInitialize(int,pvmc_last_barrier_num);
+  CpvAccess(pvmc_last_at_barrier_num)=0;
+  CpvInitialize(int,pvmc_last_barrier_num);
+  CpvAccess(pvmc_last_at_barrier_num)=0;
+}
+
+int pvm_joingroup(const char *group)
+{
+  PRINTF("TID %d joining group %s -- group support is limited\n",pvm_mytid(),group);
+
+  return pvm_mytid();
+}
+
+int pvm_lvgroup(const char *group)
+{
+  PRINTF("TID %d leaving group %s -- group support is limited\n",pvm_mytid(),group);
+
+  return 0;
+}
+
+int pvm_bcast(const char *group, int msgtag)
+{
+  int i;
+  int return_val=0;
+
+  for(i=0; i<NUMPES(); i++)
+    if(i!=MYPE())
+      return_val+=pvm_send(PE2TID(i),msgtag);
+
+  return return_val;
+
+}
+
+int pvm_barrier(const char *group, int count)
+{
+  int i;
+  
+#ifdef PVM_DEBUG
+  PRINTF("Pe(%d) tid=%d:pvm_barrier(%s,%d) waiting for barrier %d\n",
+       MYPE(),pvm_mytid(),group,count,CpvAccess(pvmc_last_barrier_num)+1);
+#endif
+
+  /*
+   * First, everyone except Node 0 sends a message to node 0
+   */
+  if (MYPE() != 0)
+    pvmc_send_control_msg(PVMC_CTRL_AT_BARRIER,0);
+
+  /* 
+   * Node 0 will wait for NUMPES-1 messages, then send the response back
+   */
+  if (MYPE() == 0)
+  {
+    while(CpvAccess(pvmc_at_barrier_num) < 
+         CpvAccess(pvmc_last_at_barrier_num) + NUMPES()-1)
+    {
+      /* Empty network buffer */
+      while(CmiDeliverMsgs(1)==0)
+       ;
+    }
+    /*
+     * Now, node 0 has received the proper number of messages, so it must
+     * tell the other nodes to continue
+     */
+    for (i=1; i < NUMPES(); i++)
+      pvmc_send_control_msg(PVMC_CTRL_THROUGH_BARRIER,i);
+    /*
+     * Now node 0 must set itself up for the next call
+     */
+    CpvAccess(pvmc_last_at_barrier_num) += NUMPES() - 1;
+    /*
+     * And finally, node 0 tells itself that it has passed the barrier
+     */
+    CpvAccess(pvmc_barrier_num)++;
+  }
+
+  /*
+   * Now, all processors wait for barrier passage, by looking 
+   * at pvmc_barrier_num counter
+   */
+  while(CpvAccess(pvmc_barrier_num) ==         CpvAccess(pvmc_last_barrier_num))
+  {
+    /* Empty network buffer */
+    while(CmiDeliverMsgs(1)==0)
+      ;
+  }
+  /*
+   *  Barrier reached. Set up for next barrier
+   */
+  CpvAccess(pvmc_last_barrier_num)++;
+  
+}
+
diff --git a/src/langs/pvmc/pvmc_main.c b/src/langs/pvmc/pvmc_main.c
new file mode 100644 (file)
index 0000000..b5fe13c
--- /dev/null
@@ -0,0 +1,23 @@
+#include "converse.h"
+
+user_main(argc, argv)
+int argc;
+char *argv[];
+{
+  CmiPrintf("user_main probably not currently working\n");
+  /*  ConverseInit(argv); */
+
+  pvmc_init_bufs();
+#ifdef PVM_DEBUG
+  CmiPrintf("Calling pvmc_init_comm()\n");
+#endif
+
+  pvmc_init_comm();
+
+#ifdef PVM_DEBUG
+  CmiPrintf("Starting pvmc_user_main\n");
+#endif
+
+  pvmc_user_main(argc,argv);
+}
+
diff --git a/src/langs/pvmc/pvmc_pack.c b/src/langs/pvmc/pvmc_pack.c
new file mode 100644 (file)
index 0000000..ef031c5
--- /dev/null
@@ -0,0 +1,702 @@
+#include <stddef.h>
+#include "converse.h"
+#include "pvmc.h"
+
+#ifdef PVM_DEBUG
+#define PARG(x)        PRINTF("Pe(%d) %s:%d %s(,%d,%d) called.\n",MYPE(),__FILE__,__LINE__,x,cnt,std);
+#endif
+
+int pvm_upkbyte(char *cp, int cnt, int std)
+{
+  int i, n_bytes;
+  char *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkbyte");
+#endif
+
+  n_bytes = cnt * sizeof(char);
+
+  buf = (char *)pvmc_getitem(n_bytes,PVM_BYTE);
+
+  if (buf==(char *)NULL) {
+    PRINTF("%s:%d pvm_upkbyte() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(cp, buf, n_bytes);
+  } else {
+    /* For characters, word alignment doesn't matter, so do C copies */
+    for(i=0; i<cnt; i++)
+      cp[i*std] = buf[i];
+  }
+  return 0;
+}
+
+int pvm_upkcplx(float *xp, int cnt, int std)
+{
+  int i, n_bytes;
+  float *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkcplx");
+#endif
+
+  n_bytes = cnt * 2 * sizeof(float);
+
+  buf = (float *)pvmc_getitem(n_bytes,PVM_CPLX);
+
+  if (buf==(float *)NULL) {
+    PRINTF("%s:%d pvm_upkcplx() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(xp, buf, n_bytes);
+  } else {
+    /* do a separate memcopy for each pair of elements.  Very ugly,
+     * but otherwise, word alignment problems
+     */
+    for(i=0; i<cnt; i++)
+      memcpy(xp+2*i*std,buf+2*i,2*sizeof(float));
+  }
+  return 0;
+}
+
+int pvm_upkdcplx(double *zp, int cnt, int std)
+{
+  int i, n_bytes;
+  double *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkdcplx");
+#endif
+
+  n_bytes = cnt * 2 * sizeof(double);
+
+  buf = (double *)pvmc_getitem(n_bytes,PVM_DCPLX);
+
+  if (buf==(double *)NULL) {
+    PRINTF("%s:%d pvm_upkdcplx() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(zp, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(zp+2*i*std,buf+2*i,2*sizeof(double));
+  }
+  return 0;
+}
+
+int pvm_upkdouble(double *dp, int cnt, int std)
+{
+  int i, n_bytes;
+  double *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkdouble");
+#endif
+
+  n_bytes = cnt * sizeof(double);
+
+  buf = (double *)pvmc_getitem(n_bytes,PVM_DOUBLE);
+
+  if (buf==(double *)NULL) {
+    PRINTF("%s:%d pvm_upkdouble() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(dp, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(dp+i*std,buf+i,sizeof(double));
+  }
+
+  return 0;
+}
+
+int pvm_upkfloat(float *fp, int cnt, int std)
+{
+  int i, n_bytes;
+  float *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkfloat");
+#endif
+
+  n_bytes = cnt * sizeof(float);
+
+  buf = (float *)pvmc_getitem(n_bytes,PVM_FLOAT);
+
+  if (buf==(float *)NULL) {
+    PRINTF("%s:%d pvm_upkfloat() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(fp, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(fp+i*std,buf+i,sizeof(float));
+  }
+  return 0;
+}
+
+int pvm_upkint(int *np, int cnt, int std)
+{
+  int i, n_bytes;
+  int *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkint");
+#endif
+
+  n_bytes = cnt * sizeof(int);
+
+  buf = (int *)pvmc_getitem(n_bytes,PVM_INT);
+
+  if (buf==(int *)NULL) {
+    PRINTF("%s:%d pvm_upkint() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(np, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(np+i*std,buf+i,sizeof(int));
+  }
+  return 0;
+}
+
+int pvm_upkuint(unsigned int *np, int cnt, int std)
+{
+  int i, n_bytes;
+  unsigned int *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkuint");
+#endif
+
+  n_bytes = cnt * sizeof(unsigned int);
+
+  buf = (unsigned int *)pvmc_getitem(n_bytes,PVM_UINT);
+
+  if (buf==(unsigned int *)NULL) {
+    PRINTF("%s:%d pvm_upkuint() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(np, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(np+i*std,buf+i,sizeof(unsigned int));
+  }
+  return 0;
+}
+
+int pvm_upklong(long *np, int cnt, int std)
+{
+  int i, n_bytes;
+  long *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upklong");
+#endif
+
+  n_bytes = cnt * sizeof(long);
+
+  buf = (long *)pvmc_getitem(n_bytes,PVM_LONG);
+
+  if (buf==(long *)NULL) {
+    PRINTF("%s:%d pvm_upklong() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(np, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(np+i*std,buf+i,sizeof(long));
+  }
+  return 0;
+}
+
+int pvm_upkulong(unsigned long *np, int cnt, int std)
+{
+  int i, n_bytes;
+  unsigned long *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkulong");
+#endif
+
+  n_bytes = cnt * sizeof(unsigned long);
+
+  buf = (unsigned long *)pvmc_getitem(n_bytes,PVM_ULONG);
+
+  if (buf==(unsigned long *)NULL) {
+    PRINTF("%s:%d pvm_upkulong() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(np, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(np+i*std,buf+i,sizeof(unsigned long));
+  }
+  return 0;
+}
+
+int pvm_upkshort(short *np, int cnt, int std)
+{
+  int i, n_bytes;
+  short *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkshort");
+#endif
+
+  n_bytes = cnt * sizeof(short);
+
+  buf = (short *)pvmc_getitem(n_bytes,PVM_SHORT);
+
+  if (buf==(short *)NULL) {
+    PRINTF("%s:%d pvm_upkshort() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(np, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(np+i*std,buf+i,sizeof(short));
+  }
+  return 0;
+}
+
+int pvm_upkushort(unsigned short *np, int cnt, int std)
+{
+  int i, n_bytes;
+  unsigned short *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_upkushort");
+#endif
+
+  n_bytes = cnt * sizeof(unsigned short);
+
+  buf = (unsigned short *)pvmc_getitem(n_bytes,PVM_USHORT);
+
+  if (buf==(unsigned short *)NULL) {
+    PRINTF("%s:%d pvm_upkushort() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (std==1) {
+    memcpy(np, buf, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      memcpy(np+i*std,buf+i,sizeof(unsigned short));
+  }
+  return 0;
+}
+
+int pvm_upkstr(char *cp)
+{
+  int i, n_bytes;
+  short *buf;
+
+#ifdef PVM_DEBUG
+  PRINTF("%s:%d %s() called.",__FILE__,__LINE__,"pvm_upkstr");
+#endif
+
+  buf = (short *)pvmc_getstritem(&n_bytes);
+
+  if (buf==(short *)NULL) {
+    PRINTF("%s:%d pvm_upkshort() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  memcpy(cp, buf, n_bytes);
+  cp[n_bytes]='\0';
+
+  return 0;
+}
+
+/**********************************************************************/
+
+int pvm_pkbyte(char *cp, int cnt, int std)
+{
+  int i, n_bytes;
+  char *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkbyte");
+#endif
+
+  n_bytes = cnt * sizeof(char);
+
+  buf = (char *)pvmc_mkitem(n_bytes,PVM_BYTE);
+
+  if (buf==(char *)NULL) {
+    PRINTF("%s:%d pvm_pkbyte() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*cp;
+  else if (std==1) {
+    memcpy(buf, cp, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++)
+      buf[i]=cp[i*std];
+  }
+  return 0;
+}
+
+int pvm_pkcplx(float *xp, int cnt, int std)
+{
+  int i, n_bytes;
+  float *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkcplx");
+#endif
+
+  n_bytes = cnt*2*sizeof(float);
+
+  buf = (float *)pvmc_mkitem(n_bytes,PVM_CPLX);
+
+  if (buf==(float *)NULL) {
+    PRINTF("%s:%d pvm_pkcplx() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*xp;
+  else if (std==1) {
+    memcpy(buf, xp, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[2*i]=xp[i*std];
+      buf[2*i+1]=xp[i*std+1];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkdcplx(double *zp, int cnt, int std)
+{
+  int i, n_bytes;
+  double *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkdcplx");
+#endif
+
+  n_bytes = cnt*2*sizeof(double);
+
+  buf = (double *)pvmc_mkitem(n_bytes,PVM_DCPLX);
+  if (buf==(double *)NULL) {
+    PRINTF("%s:%d pvm_pkdcplx() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*zp;
+  else if (std==1) {
+    memcpy(buf, zp, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[2*i]=zp[i*std];
+      buf[2*i+1]=zp[i*std+1];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkdouble(double *dp, int cnt, int std)
+{
+  int i, n_bytes;
+  double *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkdouble");
+#endif
+
+  n_bytes = cnt*sizeof(double);
+
+  buf = (double *)pvmc_mkitem(n_bytes,PVM_DOUBLE);
+  if (buf==(double *)NULL) {
+    PRINTF("%s:%d pvm_pkdouble() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*dp;
+  else if (std==1) {
+    memcpy(buf, dp, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[i]=dp[i*std];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkfloat(float *fp, int cnt, int std)
+{
+  int i, n_bytes;
+  float *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkfloat");
+#endif
+
+  n_bytes = cnt*sizeof(float);
+
+  buf = (float *)pvmc_mkitem(n_bytes,PVM_FLOAT);
+  if (buf==(float *)NULL) {
+    PRINTF("%s:%d pvm_pkfloat() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*fp;
+  else if (std==1) {
+    memcpy(buf, fp, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[i]=fp[i*std];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkint(int *np, int cnt, int std)
+{
+  int i, n_bytes;
+  int *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkint");
+#endif
+
+  n_bytes = cnt*sizeof(int);
+
+  buf = (int *)pvmc_mkitem(n_bytes,PVM_INT);
+  if (buf==(int *)NULL) {
+    PRINTF("%s:%d pvm_pkint() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*np;
+  else if (std==1) {
+    memcpy(buf, np, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[i]=np[i*std];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkuint(unsigned int *np, int cnt, int std)
+{
+  int i, n_bytes;
+  unsigned int *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkuint");
+#endif
+
+  n_bytes = cnt*sizeof(unsigned int);
+
+  buf = (unsigned int *)pvmc_mkitem(n_bytes,PVM_UINT);
+  if (buf==(unsigned int *)NULL) {
+    PRINTF("%s:%d pvm_pkuint() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*np;
+  else if (std==1) {
+    memcpy(buf, np, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[i]=np[i*std];
+    }
+  }
+  return 0;
+}
+
+int pvm_pklong(long *np, int cnt, int std)
+{
+  int i, n_bytes;
+  long *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pklong");
+#endif
+
+  n_bytes = cnt*sizeof(long);
+
+  buf = (long *)pvmc_mkitem(n_bytes,PVM_LONG);
+  if (buf==(long *)NULL) {
+    PRINTF("%s:%d pvm_pklong() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*np;
+  else if (std==1) {
+    memcpy(buf, np, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[i]=np[i*std];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkulong(unsigned long *np, int cnt, int std)
+{
+  int i, n_bytes;
+  unsigned long *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkulong");
+#endif
+
+  n_bytes = cnt*sizeof(unsigned long);
+
+  buf = (unsigned long *)pvmc_mkitem(n_bytes,PVM_ULONG);
+  if (buf==(unsigned long *)NULL) {
+    PRINTF("%s:%d pvm_pkulong() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*np;
+  else if (std==1) {
+    memcpy(buf, np, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[i]=np[i*std];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkshort(short *np, int cnt, int std)
+{
+  int i, n_bytes;
+  short *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkshort");
+#endif
+
+  n_bytes = cnt*sizeof(short);
+
+  buf = (short *)pvmc_mkitem(n_bytes,PVM_SHORT);
+  if (buf==(short *)NULL) {
+    PRINTF("%s:%d pvm_pkshort() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*np;
+  else if (std==1) {
+    memcpy(buf, np, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[i]=np[i*std];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkushort(unsigned short *np, int cnt, int std)
+{
+  int i, n_bytes;
+  unsigned short *buf;
+
+#ifdef PVM_DEBUG
+  PARG("pvm_pkushort");
+#endif
+
+  n_bytes = cnt*sizeof(unsigned short);
+
+  buf = (unsigned short *)pvmc_mkitem(n_bytes,PVM_USHORT);
+  if (buf==(unsigned short *)NULL) {
+    PRINTF("%s:%d pvm_pkushort() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  if (cnt==1)
+    *buf=*np;
+  else if (std==1) {
+    memcpy(buf, np, n_bytes);
+  } else {
+    for(i=0; i<cnt; i++) {
+      buf[i]=np[i*std];
+    }
+  }
+  return 0;
+}
+
+int pvm_pkstr(char *cp)
+{
+  int i, n_bytes;
+  char *buf;
+
+#ifdef PVM_DEBUG
+  PRINTF("%s:%d %s() called.",__FILE__,__LINE__,"pvm_pkstr");
+#endif
+
+  n_bytes = strlen(cp);
+
+  buf = (char *)pvmc_mkitem(n_bytes,PVM_STR);
+  if (buf==(char *)NULL) {
+    PRINTF("%s:%d pvm_pkstr() no data mem\n",
+          __FILE__,__LINE__);
+    return -1;
+  }
+
+  memcpy(buf, cp, n_bytes);
+
+  return 0;
+}
+
diff --git a/src/langs/pvmc/pvmctest.c b/src/langs/pvmc/pvmctest.c
new file mode 100644 (file)
index 0000000..5007da4
--- /dev/null
@@ -0,0 +1,215 @@
+#include <stdio.h>
+#include <sys/time.h>
+#include <math.h>
+#include "pvm3.h"
+#include <converse.h>
+
+/* #include <sys/types.h> */
+/* #include <fcntl.h> */
+
+#define MALLOC(x) CmiAlloc(x)
+#define PRINTF CmiPrintf
+#define puts(x) CmiPrintf("%s%c",(x),'\n')
+
+pvmc_user_main(argc,argv)
+{
+  if (CmiMyPe()==0) {
+    time_master(argc,argv);
+  } else {
+    time_slave(argc,argv);
+  }
+  exit(1);
+}
+
+/*
+*       timing.c
+*
+*       Does a few communication timing tests on pvm.
+*       Uses `timing_slave' to echo messages.
+*
+*       9 Dec 1991  Manchek
+*  14 Oct 1992  Geist  - revision to pvm3
+*/
+
+
+#define SLAVENAME "timeslave"
+
+time_master(argc, argv)
+int argc;
+char **argv;
+{
+  int mytid;                  /* my task id */
+  int stid = 0;               /* slave task id */
+  int reps = 20;              /* number of samples per test */
+  struct timeval tv1, tv2;    /* for timing */
+  int dt1, dt2;               /* time for one iter */
+  int at1, at2;               /* accum. time */
+  int numint;                 /* message length */
+  int n;
+  int i;
+  int *iarray = 0;
+
+  /* enroll in pvm */
+
+  if ((mytid = pvm_mytid()) < 0) {
+    exit(1);
+  }
+  PRINTF("i'm t%x\n", mytid);
+
+  /* start up slave task */
+  /*        PRINTF("Argc==%d, name == %s\n", argc, argv[1]);*/
+  if (argc>1)  /* read it of the command line */
+    {
+      if (pvm_spawn(SLAVENAME, (char **)0, PvmTaskHost, argv[1], 1, &stid) <=0 || stid < 0) {
+       fputs("can't initiate slave on ", stderr);
+       fputs(argv[1], stderr);
+       fputs("\n", stderr);
+       goto bail;
+      }
+    }
+  else   /* let the pvmd decide */
+    if (pvm_spawn(SLAVENAME, (char**)0, 0, "", 1, &stid) <= 0 || stid < 0) {
+      fputs("can't initiate slave\n", stderr);
+      goto bail;
+    }
+
+  PRINTF("slave is task t%x\n", stid);
+
+  /*
+   *  round-trip timing test
+   */
+
+  puts("Doing Round Trip test, minimal message size\n");
+  at1 = 0;
+
+  /* pack buffer */
+
+  pvm_initsend(PvmDataRaw);
+  pvm_pkint(&stid, 1, 1);
+
+  puts(" N     uSec");
+  for (n = 1; n <= reps; n++) {
+    gettimeofday(&tv1, (struct timezone*)0);
+
+    if (pvm_send(stid, 1)) {
+      PRINTF("can't send to \"%s\"\n", SLAVENAME);
+      goto bail;
+    }
+
+    if (pvm_recv(-1, -1) < 0) {
+      PRINTF("recv error%d\n" );
+      goto bail;
+    }
+
+    gettimeofday(&tv2, (struct timezone*)0);
+
+    dt1 = (tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec;
+    /*                PRINTF("(sec = %d %d, usec = %d %d) %2d %8d\n", tv2.tv_sec, tv1.tv_sec, tv2.tv_usec, tv1.tv_usec, n, dt1);*/
+    PRINTF("TIME 0 %2d %8d\n", n, dt1);
+    at1 += dt1;
+  }
+  PRINTF("RTT Avg uSec %d\n", at1 / reps);
+
+  /*
+   *  bandwidth test for different message lengths
+   */
+
+  puts("\nDoing Bandwidth tests\n");
+
+  for (numint = 25; numint < 100000; numint *= 10) {
+    PRINTF("\nMessage size is %d integers (%d bytes)\n", 
+          numint, numint * sizeof(int));
+    at1 = at2 = 0;
+    iarray = (int*)MALLOC(numint * sizeof(int));
+    puts(" N  Pack uSec  Send uSec");
+    for (n = 1; n <= reps; n++) {
+      gettimeofday(&tv1, (struct timezone*)0);
+
+      pvm_initsend(PvmDataRaw);
+      pvm_pkint(iarray, numint, 1);
+
+      gettimeofday(&tv2, (struct timezone*)0);
+      dt1 = (tv2.tv_sec - tv1.tv_sec) * 1000000
+       + tv2.tv_usec - tv1.tv_usec;
+
+      gettimeofday(&tv1, (struct timezone*)0);
+
+      if (pvm_send(stid, 1)) {
+       PRINTF("can't send to \"%s\"\n", SLAVENAME);
+       goto bail;
+      }
+
+      if (pvm_recv(-1, -1) < 0) {
+       PRINTF("recv error%d\n" );
+       goto bail;
+      }
+
+      gettimeofday(&tv2, (struct timezone*)0);
+      dt2 = (tv2.tv_sec - tv1.tv_sec) * 1000000
+       + tv2.tv_usec - tv1.tv_usec;
+
+      PRINTF("TIME %d %2d   %8d   %8d   %8d\n", sizeof(int)*numint, n, dt1, dt2,dt1+dt2);
+      at1 += dt1;
+      at2 += dt2;
+    }
+
+    puts("Total uSec");
+    PRINTF("     %8d   %8d   %8d\n", at1, at2,at1+at2);
+
+    at1 /= reps;
+    at2 /= reps;
+    puts("Avg uSec");
+    PRINTF("     %8d   %8d\n", at1, at2);
+    puts("Avg Byte/uSec");
+    PRINTF("     %8f   %8f\n",
+          (numint * 4) / (double)at1,
+          (numint * 4) / (double)at2);
+  }
+
+  puts("\ndone");
+
+bail:
+  if (stid > 0)
+    pvm_kill(stid);
+  sleep(10);
+  pvm_exit();
+  exit(1);
+}
+
+
+/*
+*       timing_slave.c
+*
+*       See timing.c
+*/
+
+time_slave(argc, argv)
+int argc;
+char **argv;
+{
+  int mytid;   /* my task id */
+  int dtid;    /* driver task */
+  int bufid;
+  int n = 0;
+
+  /* enroll in pvm */
+
+  mytid = pvm_mytid();
+
+  /* pack mytid in buffer */
+
+  pvm_initsend(PvmDataRaw);
+  pvm_pkint(&mytid, 1, 1);
+
+  /* our job is just to echo back to the sender when we get a message */
+
+  while (1) {
+    bufid = pvm_recv(-1, -1);
+    pvm_bufinfo(bufid, (int*)0, (int*)0, &dtid);
+    pvm_send(dtid, 2);
+    /*
+      PRINTF("echo %d\n", ++n);
+      */
+  }
+}
+