Removed almost all warnings on origin2000.
[charm.git] / src / conv-ldb / cldb.c
1 #include "cldb.h"
2
3 /* Estimator stuff.  Of any use? */
4 /*
5 CpvStaticDeclare(CldEstimatorTable, _estfns);
6 */
7 void CldRegisterEstimator(CldEstimator fn)
8 {
9   /*CpvAccess(_estfns).fns[CpvAccess(_estfns).count++] = fn;*/
10 }
11
12 /* 
13 int CldEstimate(void)
14 {
15   CldEstimatorTable *estab = &(CpvAccess(_estfns));
16   int i, load=0;
17   for(i=0; i<estab->count; i++)
18     load += (*(estab->fns[i]))();
19   return load;
20 }
21
22 static int CsdEstimator(void)
23 {
24   return CsdLength();
25 }
26 */
27
28 CpvDeclare(int, CldLoadOffset);
29
30 int CldRegisterInfoFn(CldInfoFn fn)
31 {
32   return CmiRegisterHandler((CmiHandler)fn);
33 }
34
35 int CldRegisterPackFn(CldPackFn fn)
36 {
37   return CmiRegisterHandler((CmiHandler)fn);
38 }
39
40 /* CldSwitchHandler takes a message and a new handler number.  It
41  * changes the handler number to the new handler number and move the
42  * old to the Xhandler part of the header.  When the message gets
43  * handled, the handler should call CldRestoreHandler to put the old
44  * handler back.
45  *
46  * CldPutToken puts a message in the scheduler queue in such a way
47  * that it can be retreived from the queue.  Once the message gets
48  * handled, it can no longer be retreived.  CldGetToken removes a
49  * message that was placed in the scheduler queue in this way.
50  * CldCountTokens tells you how many tokens are currently retreivable.  
51 */
52
53 void CldSwitchHandler(char *cmsg, int handler)
54 {
55   CmiSetXHandler(cmsg, CmiGetHandler(cmsg));
56   CmiSetHandler(cmsg, handler);
57 }
58
59 void CldRestoreHandler(char *cmsg)
60 {
61   CmiSetHandler(cmsg, CmiGetXHandler(cmsg));
62 }
63
64 void Cldhandler(char *);
65  
66 typedef struct CldToken_s {
67   char msg_header[CmiMsgHeaderSizeBytes];
68   char *msg;  /* if null, message already removed */
69   struct CldToken_s *pred;
70   struct CldToken_s *succ;
71 } *CldToken;
72
73 typedef struct CldProcInfo_s {
74   int tokenhandleridx;
75   int load; /* number of items in doubly-linked circle besides sentinel */
76   CldToken sentinel;
77 } *CldProcInfo;
78
79 CpvDeclare(CldProcInfo, CldProc);
80
81 static void CldTokenHandler(CldToken tok)
82 {
83   CldProcInfo proc = CpvAccess(CldProc);
84   if (tok->msg) {
85     tok->pred->succ = tok->succ;
86     tok->succ->pred = tok->pred;
87     proc->load --;
88     CmiHandleMessage(tok->msg);
89   }
90   else 
91     CpvAccess(CldLoadOffset)--;
92 }
93
94 int CldCountTokens()
95 {
96   return (CpvAccess(CldProc)->load);
97 }
98
99 int CldLoad()
100 {
101   return (CsdLength() - CpvAccess(CldLoadOffset));
102 }
103
104 void CldPutToken(char *msg)
105 {
106   CldProcInfo proc = CpvAccess(CldProc);
107   CldInfoFn ifn = (CldInfoFn)CmiHandlerToFunction(CmiGetInfo(msg));
108   CldToken tok = (CldToken)CmiAlloc(sizeof(struct CldToken_s));
109   int len, queueing, priobits; unsigned int *prioptr;
110   CldPackFn pfn;
111
112   tok->msg = msg;
113
114   /* add token to the doubly-linked circle */
115   tok->pred = proc->sentinel->pred;
116   tok->succ = proc->sentinel;
117   tok->pred->succ = tok;
118   tok->succ->pred = tok;
119   proc->load ++;
120   
121   /* add token to the scheduler */
122   CmiSetHandler(tok, proc->tokenhandleridx);
123   ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
124
125   queueing = CQS_QUEUEING_LIFO; 
126   CsdEnqueueGeneral(tok, queueing, priobits, prioptr);
127 }
128
129 void CldGetToken(char **msg)
130 {
131   CldProcInfo proc = CpvAccess(CldProc);
132   CldToken tok;
133   
134   tok = proc->sentinel->succ;
135   if (tok == proc->sentinel) {
136     *msg = 0; return;
137   }
138   tok->pred->succ = tok->succ;
139   tok->succ->pred = tok->pred;
140   proc->load --;
141   *msg = tok->msg;
142   tok->msg = 0;
143   CpvAccess(CldLoadOffset)++;
144 }
145
146 void CldModuleGeneralInit()
147 {
148   CldToken sentinel = (CldToken)CmiAlloc(sizeof(struct CldToken_s));
149   CldProcInfo proc;
150
151   CpvInitialize(CldProcInfo, CldProc);
152   CpvInitialize(int, CldLoadOffset);
153   CpvAccess(CldLoadOffset) = 0;
154   CpvAccess(CldProc) = (CldProcInfo)CmiAlloc(sizeof(struct CldProcInfo_s));
155   proc = CpvAccess(CldProc);
156   proc->load = 0;
157   proc->tokenhandleridx = CmiRegisterHandler((CmiHandler)CldTokenHandler);
158   proc->sentinel = sentinel;
159   sentinel->succ = sentinel;
160   sentinel->pred = sentinel;
161 }
162
163 void CldMultipleSend(int pe, int numToSend)
164 {
165   char **msgs;
166   int len, queueing, priobits, *msgSizes, i, numSent, done=0, parcelSize;
167   unsigned int *prioptr;
168   CldInfoFn ifn;
169   CldPackFn pfn;
170
171   if (numToSend == 0)
172     return;
173   msgs = (char **)calloc(numToSend, sizeof(char *));
174   msgSizes = (int *)calloc(numToSend, sizeof(int));
175
176   while (!done) {
177     numSent = 0;
178     parcelSize = 0;
179     for (i=0; i<numToSend; i++) {
180       CldGetToken(&msgs[i]);
181       if (msgs[i] != 0) {
182         done = 1;
183         numSent++;
184         ifn = (CldInfoFn)CmiHandlerToFunction(CmiGetInfo(msgs[i]));
185         ifn(msgs[i], &pfn, &len, &queueing, &priobits, &prioptr);
186         msgSizes[i] = len;
187         parcelSize += len;
188         CldSwitchHandler(msgs[i], CpvAccess(CldBalanceHandlerIndex));
189       }
190       else {
191         done = 1;
192         break;
193       }
194       if (parcelSize > MAXMSGBFRSIZE) {
195         if(i<numToSend-1)
196           done = 0;
197         numToSend -= numSent;
198         break;
199       }
200     }
201     if (numSent > 1) {
202       CmiMultipleSend(pe, numSent, msgSizes, msgs);
203       for (i=0; i<numSent; i++)
204         CmiFree(msgs[i]);
205       CpvAccess(CldRelocatedMessages) += numSent;
206       CpvAccess(CldMessageChunks)++;
207     }
208     else if (numSent == 1) {
209       CmiSyncSend(pe, msgSizes[0], msgs[0]);
210       CmiFree(msgs[0]);
211       CpvAccess(CldRelocatedMessages)++;
212       CpvAccess(CldMessageChunks)++;
213     }
214   }
215   free(msgs);
216   free(msgSizes);
217 }