optimize chkp after ldb
[charm.git] / src / langs / simplemsg / sm.c
1 #include <converse.h>
2 #include "sm.h"
3
4 typedef struct SMMessageStruct *SMMessage;
5
6 struct SMMessageStruct
7 {
8   char cmiheader[CmiMsgHeaderSizeBytes];
9   int seqno, size, ntags;
10   int tags[1];
11 };
12
13 CpvStaticDeclare(int, SMHandlerIndex);
14 CpvStaticDeclare(int *, SMSeqOut);
15 CpvStaticDeclare(int *, SMSeqIn);
16 CpvStaticDeclare(CmmTable, SMMessages);
17
18 void SMHandler(m)
19 SMMessage m;
20 {
21   CmmPut(CpvAccess(SMMessages), m->ntags, m->tags, m);
22 }
23
24 void SMInit(argv)
25 char **argv;
26 {
27   int *seqout, *seqin; int i;
28
29   seqout = (int *)CmiAlloc(CmiNumPes()*sizeof(int));
30   seqin  = (int *)CmiAlloc(CmiNumPes()*sizeof(int));
31   for (i=0; i<CmiNumPes(); i++) seqout[i] = 0;
32   for (i=0; i<CmiNumPes(); i++) seqin [i] = 0;
33
34   CpvInitialize(int, SMHandlerIndex);
35   CpvInitialize(int *, SMSeqOut);
36   CpvInitialize(int *, SMSeqIn);
37   CpvInitialize(CmmTable, SMMessages);
38
39   CpvAccess(SMHandlerIndex) = CmiRegisterHandler(SMHandler);
40   CpvAccess(SMSeqOut) = seqout;
41   CpvAccess(SMSeqIn) = seqin;
42   CpvAccess(SMMessages) = CmmNew();
43 }
44
45 void GeneralSend(pe, ntags, tags, buffer, buflen)
46 int pe, ntags;
47 int *tags;
48 void *buffer;
49 int buflen;
50 {
51   int headsize, totsize, i; SMMessage msg;
52
53   headsize = sizeof(struct SMMessageStruct) + (ntags*sizeof(int));
54   headsize = ((headsize + 7) & (~7));
55   totsize = headsize + buflen;
56   msg = (SMMessage)CmiAlloc(totsize);
57   CmiSetHandler(msg, CpvAccess(SMHandlerIndex));
58   msg->seqno = (CpvAccess(SMSeqOut)[pe])++;
59   msg->size = buflen;
60   msg->ntags = ntags;
61   for (i=0; i<ntags; i++) msg->tags[i] = tags[i];
62   memcpy((((char *)msg)+headsize), buffer, buflen);
63   CmiSyncSend(pe, totsize, msg);
64 }
65
66 int GeneralBroadcast(rootpe, ntags, tags, buffer, buflen, rtags)
67 int rootpe, ntags;
68 int *tags, *rtags;
69 void *buffer;
70 int buflen;
71 {
72   if(CmiMyPe()==rootpe) {
73     int headsize, totsize, i; SMMessage msg;
74
75     headsize = sizeof(struct SMMessageStruct) + (ntags*sizeof(int));
76     headsize = ((headsize + 7) & (~7));
77     totsize = headsize + buflen;
78     msg = (SMMessage)CmiAlloc(totsize);
79     CmiSetHandler(msg, CpvAccess(SMHandlerIndex));
80     msg->size = buflen;
81     msg->ntags = ntags;
82     for (i=0; i<ntags; i++) msg->tags[i] = tags[i];
83     memcpy((((char *)msg)+headsize), buffer, buflen);
84     CmiSyncBroadcast(totsize, msg);
85     return buflen;
86   } else {
87     SMMessage msg;
88     int headsize;
89   
90     while (1) {  
91       msg = (SMMessage)CmmGet(CpvAccess(SMMessages), ntags, tags, rtags);
92       if (msg) break;
93     }
94     if (msg->size > buflen) buflen = msg->size;
95     headsize = sizeof(struct SMMessageStruct) + ((ntags-1)*sizeof(int));
96     headsize = ((headsize + 7) & (~7));
97     memcpy(buffer, ((char *)msg)+headsize, buflen);
98     CmiFree(msg);
99     return buflen;
100   }
101 }
102
103 int GeneralRecv(ntags, tags, buffer, buflen, rtags)
104 int ntags;
105 int *tags;
106 void *buffer;
107 int buflen;
108 int *rtags;
109 {
110   SMMessage msg;
111   int headsize;
112
113   while (1) {  
114     CsdScheduler(0);
115     msg = (SMMessage)CmmGet(CpvAccess(SMMessages), ntags, tags, rtags);
116     if (msg) break;
117   }
118   
119   if (msg->size > buflen) buflen = msg->size;
120   headsize = sizeof(struct SMMessageStruct) + ((ntags-1)*sizeof(int));
121   headsize = ((headsize + 7) & (~7));
122   memcpy(buffer, ((char *)msg)+headsize, buflen);
123   CmiFree(msg);
124   return buflen;
125 }
126