Removed all STL template code from load balancer. Too bad STL doesn't work
[charm.git] / src / ck-ldb / LBDBManager.C
1 #include <converse.h>
2
3 #if CMK_LBDB_ON
4
5 #include <iostream.h>
6 #include "LBDBManager.h"
7
8 struct MigrateCB;
9
10 /*************************************************************
11  * LBDB Code
12  *************************************************************/
13
14 LDOMHandle LBDB::AddOM(LDOMid _userID, void* _userData, 
15                        LDCallbacks _callbacks)
16 {
17   LDOMHandle newhandle;
18
19   newhandle.ldb.handle = static_cast<void *>(this);
20   newhandle.user_ptr = _userData;
21   newhandle.id = _userID;
22
23   LBOM* om = new LBOM(this,_userID,_userData,_callbacks);
24   if (om != NULL) {
25     newhandle.handle = oms.size();
26     oms.push_back(om);
27   } else newhandle.handle = -1;
28   om->DepositHandle(newhandle);
29   omCount++;
30   return newhandle;
31 }
32
33 LDObjHandle LBDB::AddObj(LDOMHandle _h, LDObjid _id,
34                          void *_userData, CmiBool _migratable)
35 {
36   LDObjHandle newhandle;
37
38   newhandle.omhandle = _h;
39   newhandle.user_ptr = _userData;
40   newhandle.id = _id;
41   
42   LBObj *obj = new LBObj(this,_h,_id,_userData,_migratable);
43   if (obj != NULL) {
44     newhandle.handle = objs.size();
45     objs.push_back(obj);
46   } else {
47     newhandle.handle = -1;
48   }
49   obj->DepositHandle(newhandle);
50   objCount++;
51   return newhandle;
52 }
53
54 void LBDB::UnregisterObj(LDObjHandle _h)
55 {
56   ((LBObj*)objs[_h.handle])->registered=CmiFalse;
57 }
58
59 void LBDB::RegisteringObjects(LDOMHandle _h)
60 {
61   LBOM* om = (LBOM*)oms[_h.handle];
62   if (!om->RegisteringObjs()) {
63     if (oms_registering == 0)
64       localBarrier.TurnOff();
65     oms_registering++;
66     om->SetRegisteringObjs(CmiTrue);
67   }
68 }
69
70 void LBDB::DoneRegisteringObjects(LDOMHandle _h)
71 {
72   LBOM* om = (LBOM*)oms[_h.handle];
73   if (om->RegisteringObjs()) {
74     oms_registering--;
75     if (oms_registering == 0)
76       localBarrier.TurnOn();
77     om->SetRegisteringObjs(CmiFalse);
78   }
79 }
80
81
82 void LBDB::Send(LDOMHandle destOM, LDObjid destid, unsigned int bytes)
83 {
84   LBCommData* item_ptr;
85
86   if (obj_running) {
87     LBCommData item(runningObj,destOM.id,destid);
88     item_ptr = commTable->HashInsertUnique(item);
89
90 //     CmiPrintf("[%d] Sending %d from object manager %d, object {%d,%d,%d,%d}\n"
91 //            "     to object manager %d, object {%d,%d,%d,%d}\n",
92 //            CmiMyPe(),bytes,
93 //            runningObj.omhandle.id.id,
94 //            runningObj.id.id[0],runningObj.id.id[1],
95 //            runningObj.id.id[2],runningObj.id.id[3],
96 //            destOM.id.id,
97 //            destid.id[0],destid.id[1],
98 //            destid.id[2],destid.id[3]
99 //            );
100   } else {
101     LBCommData item(CmiMyPe(),destOM.id,destid);
102     item_ptr = commTable->HashInsertUnique(item);
103
104 //     CmiPrintf("[%d] Sending %d from processor %d\n"
105 //            "     to object manager %d, object {%d,%d,%d,%d}\n",
106 //            CmiMyPe(),bytes,
107 //            CmiMyPe(),
108 //            destOM.id.id,
109 //            destid.id[0],destid.id[1],
110 //            destid.id[2],destid.id[3]
111 //            );
112   }  
113   item_ptr->addMessage(bytes);
114 }
115
116 void LBDB::ClearLoads(void)
117 {
118   int i;
119   for(i=0; i < objCount; i++)
120     if (((LBObj*)objs[i])->registered)
121     {
122       ((LBObj*)objs[i])->data.wallTime = 
123         ((LBObj*)objs[i])->data.cpuTime = 0.;
124     }
125   delete commTable;
126   commTable = new LBCommTable;
127   machineUtil.Clear();
128   obj_walltime = obj_cputime = 0;
129 }
130
131 int LBDB::ObjDataCount()
132 {
133   int nitems=0;
134   int i;
135   for(i=0; i < objCount; i++)
136     if (((LBObj*)objs[i])->registered)
137       nitems++;
138   return nitems;
139 }
140
141 void LBDB::GetObjData(LDObjData *dp)
142 {
143   for(int i = 0; i < objs.size(); i++) {
144     LBObj* obj = (LBObj*) objs[i];
145     if ( obj->registered )
146       *dp++ = obj->ObjData();
147   }
148 }
149
150 void LBDB::Migrate(LDObjHandle h, int dest)
151 {
152   if (h.handle > objCount)
153     CmiPrintf("[%d] Handle %d out of range 0-%d\n",CmiMyPe(),h.handle,objCount);
154   else if (!((LBObj*)objs[h.handle])->registered)
155     CmiPrintf("[%d] Handle %d no longer registered, range 0-%d\n",
156             CmiMyPe(),h.handle,objCount);
157
158   if ((h.handle < objCount) && (((LBObj*)objs[h.handle])->registered)) {
159     LBOM *const om = (LBOM*)oms[((LBObj*)objs[h.handle])->parentOM.handle];
160     om->Migrate(h, dest);
161   }
162   return;
163 }
164
165 void LBDB::Migrated(LDObjHandle h)
166 {
167   // Object migrated, inform load balancers
168
169   for(int i=0; i < migrateCBList.size(); i++) {
170     MigrateCB* cb = (MigrateCB*)migrateCBList[i];
171     (cb->fn)(cb->data,h);
172   }
173   
174 }
175
176 void LBDB::NotifyMigrated(LDMigratedFn fn, void* data)
177 {
178   // Save migration function
179   MigrateCB* callbk = new MigrateCB;
180
181   callbk->fn = fn;
182   callbk->data = data;
183   migrateCBList.push_back((void*)callbk);
184 }
185
186 void LBDB::BackgroundLoad(double* walltime, double* cputime)
187 {
188   double totalwall;
189   double totalcpu;
190   TotalTime(&totalwall,&totalcpu);
191
192   double idle;
193   IdleTime(&idle);
194   
195   *walltime = totalwall - idle - obj_walltime;
196   *cputime = totalcpu - obj_cputime;
197 }
198
199 void LBDB::DumpDatabase()
200 {
201 #ifdef DEBUG  
202   CmiPrintf("Database contains %d object managers\n",omCount);
203   CmiPrintf("Database contains %d objects\n",objCount);
204 #endif
205 }
206
207 LDBarrierClient LocalBarrier::AddClient(LDResumeFn fn, void* data)
208 {
209   client* new_client = new client;
210   new_client->fn = fn;
211   new_client->data = data;
212   new_client->refcount = cur_refcount;
213
214   LDBarrierClient ret_val;
215   ret_val.serial = max_client;
216   clients.push_back((void*)new_client);
217   max_client++;
218
219   client_count++;
220
221   return ret_val;
222 }
223
224 void LocalBarrier::RemoveClient(LDBarrierClient c)
225 {
226   const int cnum = c.serial;
227   if (cnum < max_client && clients[cnum] != 0) {
228     delete ((client*)clients[cnum]);
229     clients[cnum] = 0;
230     client_count--;
231   }
232 }
233
234 LDBarrierReceiver LocalBarrier::AddReceiver(LDBarrierFn fn, void* data)
235 {
236   receiver* new_receiver = new receiver;
237   new_receiver->fn = fn;
238   new_receiver->data = data;
239
240   LDBarrierReceiver ret_val;
241   ret_val.serial = max_receiver;
242   receivers.push_back(new_receiver);
243   max_receiver++;
244
245   return ret_val;
246 }
247
248 void LocalBarrier::RemoveReceiver(LDBarrierReceiver c)
249 {
250   const int cnum = c.serial;
251   if (cnum < max_receiver && receivers[cnum] != 0) {
252     delete ((receiver*)receivers[cnum]);
253     receivers[cnum] = 0;
254   }
255 }
256
257 void LocalBarrier::AtBarrier(LDBarrierClient h)
258 {
259   ((client*)clients[h.serial])->refcount++;
260   at_count++;
261   CheckBarrier();
262 }
263
264 void LocalBarrier::CheckBarrier()
265 {
266   if (!on) return;
267
268   if (at_count >= client_count) {
269     CmiBool at_barrier = CmiFalse;
270
271     for(int i=0; i < max_client; i++)
272       if (clients[i] != 0 && ((client*)clients[i])->refcount >= cur_refcount)
273         at_barrier = CmiTrue;
274
275     if (at_barrier) {
276       at_count -= client_count;
277       cur_refcount++;
278       CallReceivers();
279     }
280   }
281 }
282
283 void LocalBarrier::CallReceivers(void)
284 {
285   CmiBool called_receiver=CmiFalse;
286
287 //  for(int i=0; i < max_receiver; i++)
288     for (int i=max_receiver-1; i>=0; i--)
289     if (receivers[i] != 0) {
290       ((receiver*)receivers[i])->fn(((receiver*)receivers[i])->data);
291       called_receiver = CmiTrue;
292     }
293
294   if (!called_receiver)
295     ResumeClients();
296   
297 }
298
299 void LocalBarrier::ResumeClients(void)
300 {
301   for(int i=0; i < max_client; i++)
302     if (clients[i] != 0) 
303       ((client*)clients[i])->fn(((client*)clients[i])->data);
304 }
305
306 #endif