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