Charj: Construct Range when a range is given.
[charm.git] / src / langs / simplemsg / simplemsg.c
1 #include <converse.h>
2 #include "simplemsg.h"
3
4 typedef struct CsmMessageStruct *CsmMessage;
5
6 struct CsmMessageStruct
7 {
8   char cmiheader[CmiMsgHeaderSizeBytes];
9   int seqno, size, ntags;
10   int tags[1];
11 };
12
13 CpvStaticDeclare(int, CsmHandlerIndex);
14 CpvStaticDeclare(int *, CsmSeqOut);
15 CpvStaticDeclare(int *, CsmSeqIn);
16 CpvStaticDeclare(CmmTable, CsmMessages);
17 CpvStaticDeclare(CmmTable, CsmSleepers);
18
19 void CsmHandler(m)
20 CsmMessage m;
21 {
22   CthThread t;
23   CmmPut(CpvAccess(CsmMessages), m->ntags, m->tags, m);
24   t = (CthThread)CmmGet(CpvAccess(CsmSleepers), m->ntags, m->tags, (int *)0);
25   if (t) CthAwaken(t);
26 }
27
28 void CsmInit(argv)
29 char **argv;
30 {
31   int *seqout, *seqin; int i;
32
33   seqout = (int *)CmiAlloc(CmiNumPes()*sizeof(int));
34   seqin  = (int *)CmiAlloc(CmiNumPes()*sizeof(int));
35   for (i=0; i<CmiNumPes(); i++) seqout[i] = 0;
36   for (i=0; i<CmiNumPes(); i++) seqin [i] = 0;
37
38   CpvInitialize(int, CsmHandlerIndex);
39   CpvInitialize(int *, CsmSeqOut);
40   CpvInitialize(int *, CsmSeqIn);
41   CpvInitialize(CmmTable, CsmMessages);
42   CpvInitialize(CmmTable, CsmSleepers);
43
44   CpvAccess(CsmHandlerIndex) = CmiRegisterHandler(CsmHandler);
45   CpvAccess(CsmSeqOut) = seqout;
46   CpvAccess(CsmSeqIn)  = seqin;
47   CpvAccess(CsmMessages) = CmmNew();
48   CpvAccess(CsmSleepers) = CmmNew();
49 }
50
51 void CsmTVSend(pe, ntags, tags, buffer, buflen)
52 int pe, ntags;
53 int *tags;
54 void *buffer;
55 int buflen;
56 {
57   int headsize, totsize, i; CsmMessage msg;
58
59   headsize = sizeof(struct CsmMessageStruct) + (ntags*sizeof(int));
60   headsize = ((headsize + 7) & (~7));
61   totsize = headsize + buflen;
62   msg = (CsmMessage)CmiAlloc(totsize);
63   CmiSetHandler(msg, CpvAccess(CsmHandlerIndex));
64   msg->seqno = (CpvAccess(CsmSeqOut)[pe])++;
65   msg->size = buflen;
66   msg->ntags = ntags;
67   for (i=0; i<ntags; i++) msg->tags[i] = tags[i];
68   memcpy((((char *)msg)+headsize), buffer, buflen);
69   CmiSyncSend(pe, totsize, msg);
70 }
71
72 void CsmTVRecv(ntags, tags, buffer, buflen, rtags)
73 int ntags;
74 int *tags;
75 void *buffer;
76 int buflen;
77 int *rtags;
78 {
79   CsmMessage msg; CthThread self;
80   int headsize;
81
82   while (1) {  
83     msg = (CsmMessage)CmmGet(CpvAccess(CsmMessages), ntags, tags, rtags);
84     if (msg) break;
85     self = CthSelf();
86     CmmPut(CpvAccess(CsmSleepers), ntags, tags, self);
87     CthSuspend();
88   }
89   
90   if (msg->size > buflen) buflen = msg->size;
91   headsize = sizeof(struct CsmMessageStruct) + ((ntags-1)*sizeof(int));
92   headsize = ((headsize + 7) & (~7));
93   memcpy(buffer, ((char *)msg)+headsize, buflen);
94   CmiFree(msg);
95   return;
96 }
97