doc: Add serial to list of ci file reserved words
[charm.git] / src / conv-core / cpm.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "queueing.h"
4 #include <converse.h>
5
6 static void CpmLSend(int pe, int len, void *msg)
7 {
8   if (pe==CpmALL) CmiSyncBroadcastAllAndFree(len, msg);
9   else if (pe==CpmOTHERS) CmiSyncBroadcastAndFree(len, msg);
10   else CmiSyncSendAndFree(pe,len,msg);
11 }
12
13 /******************************************************************************
14  *
15  * Control for simple-send
16  *
17  *****************************************************************************/
18
19 typedef struct CpmDestinationSend
20
21   void *(*sendfn)();
22   int envsize;
23   int pe;
24 }
25 *CpmDestinationSend;
26
27 typedef struct CpmDestinationSend DestinationSend;
28
29 void CpmSend1(CpmDestinationSend ctrl, int len, void *msg)
30 {
31   CpmLSend(ctrl->pe, len, msg);
32 }
33
34 CpvStaticDeclare(DestinationSend, ctrlSend);
35
36 CpmDestination CpmSend(int pe)
37 {
38   CpvAccess(ctrlSend).envsize = 0;
39   CpvAccess(ctrlSend).sendfn = (CpmSender)CpmSend1;
40   CpvAccess(ctrlSend).pe = pe;
41   return (CpmDestination)&CpvAccess(ctrlSend);
42 }
43
44 /******************************************************************************
45  *
46  * Control for CpmEnqueue
47  *
48  *****************************************************************************/
49
50 typedef struct CpmDestinationEnq
51 {
52   void *(*sendfn)();
53   int envsize;
54   int pe, qs, priobits;
55   unsigned int *prioptr;
56 }
57 *CpmDestinationEnq;
58
59 typedef struct CpmDestinationEnq DestinationEnq;
60
61 CpvStaticDeclare(DestinationEnq, ctrlEnq);
62
63 CpvDeclare(int, CpmEnqueue2_Index);
64
65 void CpmEnqueue2(void *msg)
66 {
67   int *env;
68   env = (int *)CpmEnv(msg);
69   CmiSetHandler(msg, env[0]);
70   CsdEnqueueGeneral(msg, env[1], env[2], (unsigned int *)(env+3));
71 }
72
73 void *CpmEnqueue1(CpmDestinationEnq ctrl, int len, void *msg)
74 {
75   int *env = (int *)CpmEnv(msg);
76   int intbits = sizeof(int)*8;
77   int priobits = ctrl->priobits;
78   int prioints = (priobits+intbits-1) / intbits;
79   env[0] = CmiGetHandler(msg);
80   env[1] = ctrl->qs;
81   env[2] = ctrl->priobits;
82   memcpy(env+3, ctrl->prioptr, prioints*sizeof(int));
83   CmiSetHandler(msg, CpvAccess(CpmEnqueue2_Index));
84   CpmLSend(ctrl->pe, len, msg);
85   return (void *) 0;
86 }
87
88 CpmDestination CpmEnqueue(int pe, int qs, int priobits,unsigned int *prioptr)
89 {
90   int intbits = sizeof(int)*8;
91   int prioints = (priobits+intbits-1) / intbits;
92   CpvAccess(ctrlEnq).envsize = (3+prioints)*sizeof(int);
93   CpvAccess(ctrlEnq).sendfn  = CpmEnqueue1;
94   CpvAccess(ctrlEnq).pe = pe; CpvAccess(ctrlEnq).qs = qs; 
95   CpvAccess(ctrlEnq).priobits = priobits; CpvAccess(ctrlEnq).prioptr = prioptr;
96   return (CpmDestination)&CpvAccess(ctrlEnq);
97 }
98
99 CpvStaticDeclare(unsigned int, fiprio);
100
101 CpmDestination CpmEnqueueIFIFO(int pe, int prio)
102 {
103   CpvAccess(fiprio) = prio;
104   return CpmEnqueue(pe, CQS_QUEUEING_IFIFO, sizeof(int)*8, &CpvAccess(fiprio));
105 }
106
107 CpvStaticDeclare(unsigned int, liprio);
108
109 CpmDestination CpmEnqueueILIFO(int pe, int prio)
110 {
111   CpvAccess(liprio) = prio;
112   return CpmEnqueue(pe, CQS_QUEUEING_ILIFO, sizeof(int)*8, &CpvAccess(liprio));
113 }
114
115 CpmDestination CpmEnqueueBFIFO(int pe, int priobits,unsigned int *prioptr)
116 {
117   return CpmEnqueue(pe, CQS_QUEUEING_BFIFO, priobits, prioptr);
118 }
119
120 CpmDestination CpmEnqueueBLIFO(int pe, int priobits,unsigned int *prioptr)
121 {
122   return CpmEnqueue(pe, CQS_QUEUEING_BLIFO, priobits, prioptr);
123 }
124
125 CpmDestination CpmEnqueueLFIFO(int pe, int priobits,unsigned int *prioptr)
126 {
127   return CpmEnqueue(pe, CQS_QUEUEING_LFIFO, priobits, prioptr);
128 }
129
130 CpmDestination CpmEnqueueLLIFO(int pe, int priobits,unsigned int *prioptr)
131 {
132   return CpmEnqueue(pe, CQS_QUEUEING_LLIFO, priobits, prioptr);
133 }
134
135 /******************************************************************************
136  *
137  * Control for Enqueue-FIFO
138  *
139  *****************************************************************************/
140
141 CpvDeclare(int, CpmEnqueueFIFO2_Index);
142
143 void CpmEnqueueFIFO2(void *msg)
144 {
145   int *env;
146   env = (int *)CpmEnv(msg);
147   CmiSetHandler(msg, env[0]);
148   CsdEnqueueFifo(msg);
149 }
150
151 void *CpmEnqueueFIFO1(CpmDestinationSend ctrl, int len, void *msg)
152 {
153   int *env = (int *)CpmEnv(msg);
154   env[0] = CmiGetHandler(msg);
155   CmiSetHandler(msg, CpvAccess(CpmEnqueueFIFO2_Index));
156   CpmLSend(ctrl->pe, len, msg);
157   return (void *) 0;
158 }
159
160 CpvStaticDeclare(DestinationSend, ctrlFIFO);
161
162 CpmDestination CpmEnqueueFIFO(int pe)
163 {
164   CpvAccess(ctrlFIFO).envsize = sizeof(int);
165   CpvAccess(ctrlFIFO).sendfn  = CpmEnqueueFIFO1;
166   CpvAccess(ctrlFIFO).pe = pe;
167   return (CpmDestination)&CpvAccess(ctrlFIFO);
168 }
169
170 /******************************************************************************
171  *
172  * Control for Enqueue-LIFO
173  *
174  *****************************************************************************/
175
176 CpvDeclare(int, CpmEnqueueLIFO2_Index);
177
178 void CpmEnqueueLIFO2(void *msg)
179 {
180   int *env;
181   env = (int *)CpmEnv(msg);
182   CmiSetHandler(msg, env[0]);
183   CsdEnqueueLifo(msg);
184 }
185
186 void *CpmEnqueueLIFO1(CpmDestinationSend ctrl, int len, void *msg)
187 {
188   int *env = (int *)CpmEnv(msg);
189   env[0] = CmiGetHandler(msg);
190   CmiSetHandler(msg, CpvAccess(CpmEnqueueLIFO2_Index));
191   CpmLSend(ctrl->pe, len, msg);
192   return (void *) 0;
193 }
194
195 CpvStaticDeclare(DestinationSend, ctrlLIFO);
196
197 CpmDestination CpmEnqueueLIFO(int pe)
198 {
199   CpvAccess(ctrlLIFO).envsize = sizeof(int);
200   CpvAccess(ctrlLIFO).sendfn  = CpmEnqueueLIFO1;
201   CpvAccess(ctrlLIFO).pe = pe;
202   return (CpmDestination)&CpvAccess(ctrlLIFO);
203 }
204
205 /******************************************************************************
206  *
207  * Control for thread-creation
208  *
209  *****************************************************************************/
210
211 CpvDeclare(int, CpmThread2_Index);
212
213 void CpmThread3(void *msg)
214 {
215   int *env = (int *)CpmEnv(msg);
216   CmiHandlerInfo *h=&CmiHandlerToInfo(env[0]);
217   (h->hdlr)(msg,h->userPtr);
218   CmiFree(msg);
219   CthFree(CthSelf()); CthSuspend();
220 }
221
222 void CpmThread2(void *msg)
223 {
224   CthThread t;
225   t = CthCreate(CpmThread3, msg, 0);
226   CthSetStrategyDefault(t); CthAwaken(t);
227 }
228
229 void CpmThread1(CpmDestinationSend ctrl, int len, void *msg)
230 {
231   int *env = (int *)CpmEnv(msg);
232   env[0] = CmiGetHandler(msg);
233   CmiSetHandler(msg, CpvAccess(CpmThread2_Index));
234   CpmLSend(ctrl->pe, len, msg);
235 }
236
237 CpvStaticDeclare(DestinationSend, ctrlThread);
238
239 CpmDestination CpmMakeThread(int pe)
240 {
241   CpvAccess(ctrlThread).envsize = sizeof(int);
242   CpvAccess(ctrlThread).sendfn = (CpmSender)CpmThread1;
243   CpvAccess(ctrlThread).pe = pe;
244   return (CpmDestination)&CpvAccess(ctrlThread);
245 }
246
247 /******************************************************************************
248  *
249  * Control for thread-creation with size parameter
250  *
251  *****************************************************************************/
252
253 CpvDeclare(int, CpmThreadSize2_Index);
254
255 typedef struct CpmDestinationThreadSize
256
257   void *(*sendfn)();
258   int envsize;
259   int pe;
260   int size;
261 }
262 *CpmDestinationThreadSize;
263
264 typedef struct CpmDestinationThreadSize DestinationThreadSize;
265
266 void CpmThreadSize2(void *msg)
267 {
268   int *env = (int *)CpmEnv(msg);
269   CthThread t;
270   t = CthCreate(CpmThread3, msg, env[1]);
271   CthSetStrategyDefault(t); CthAwaken(t);
272 }
273
274 void CpmThreadSize1(CpmDestinationThreadSize ctrl, int len, void *msg)
275 {
276   int *env = (int *)CpmEnv(msg);
277   env[0] = CmiGetHandler(msg);
278   env[1] = ctrl->size;
279   CmiSetHandler(msg, CpvAccess(CpmThreadSize2_Index));
280   CpmLSend(ctrl->pe, len, msg);
281 }
282
283 CpvStaticDeclare(DestinationThreadSize, ctrlThreadSize);
284
285 CpmDestination CpmMakeThreadSize(int pe, int size)
286 {
287   CpvAccess(ctrlThreadSize).envsize = 2*sizeof(int);
288   CpvAccess(ctrlThreadSize).sendfn = (CpmSender)CpmThreadSize1;
289   CpvAccess(ctrlThreadSize).pe = pe;
290   CpvAccess(ctrlThreadSize).size = size;
291   return (CpmDestination)&CpvAccess(ctrlThreadSize);
292 }
293
294 /******************************************************************************
295  *
296  * Cpm initialization
297  *
298  *****************************************************************************/
299
300 void CpmModuleInit()
301 {
302   CpvInitialize(int, CpmThread2_Index);
303   CpvAccess(CpmThread2_Index) = CmiRegisterHandler(CpmThread2);
304   CpvInitialize(int, CpmThreadSize2_Index);
305   CpvAccess(CpmThreadSize2_Index) = CmiRegisterHandler(CpmThreadSize2);
306   CpvInitialize(int, CpmEnqueueFIFO2_Index);
307   CpvAccess(CpmEnqueueFIFO2_Index) = CmiRegisterHandler(CpmEnqueueFIFO2);
308   CpvInitialize(int, CpmEnqueueLIFO2_Index);
309   CpvAccess(CpmEnqueueLIFO2_Index) = CmiRegisterHandler(CpmEnqueueLIFO2);
310   CpvInitialize(int, CpmEnqueue2_Index);
311   CpvAccess(CpmEnqueue2_Index) = CmiRegisterHandler(CpmEnqueue2);
312   CpvInitialize(DestinationSend, ctrlSend);
313   CpvInitialize(DestinationEnq, ctrlEnq);
314   CpvInitialize(DestinationSend, ctrlFIFO);
315   CpvInitialize(DestinationSend, ctrlLIFO);
316   CpvInitialize(DestinationSend, ctrlThread);
317   CpvInitialize(DestinationThreadSize, ctrlThreadSize);
318   CpvInitialize(unsigned int, fiprio);
319   CpvInitialize(unsigned int, liprio);
320 }
321