10e16a5b009f4a4c1804ac3c52125755940f8f92
[charm.git] / src / ck-ldb / LBDBManager.h
1 /**
2  * \addtogroup CkLdb
3 */
4 /*@{*/
5
6 #ifndef LBDB_H
7 #define LBDB_H
8
9 #include "converse.h"
10 #include "lbdb.h"
11 #include "cklists.h"
12
13 #include "LBObj.h"
14 #include "LBOM.h"
15 #include "LBComm.h"
16 #include "LBMachineUtil.h"
17
18 class LocalBarrier {
19 friend class LBDB;
20 public:
21   LocalBarrier() { cur_refcount = 1; client_count = 0; max_client = 0;
22                    max_receiver= 0; at_count = 0; on = CmiFalse; 
23         #if CMK_BIGSIM_CHARM
24         first_free_client_slot = 0;
25         #endif
26     };
27   ~LocalBarrier() { };
28
29   LDBarrierClient AddClient(LDResumeFn fn, void* data);
30   void RemoveClient(LDBarrierClient h);
31   LDBarrierReceiver AddReceiver(LDBarrierFn fn, void* data);
32   void RemoveReceiver(LDBarrierReceiver h);
33   void TurnOnReceiver(LDBarrierReceiver h);
34   void TurnOffReceiver(LDBarrierReceiver h);
35   void AtBarrier(LDBarrierClient h);
36   void TurnOn() { on = CmiTrue; CheckBarrier(); };
37   void TurnOff() { on = CmiFalse; };
38
39 private:
40   void CallReceivers(void);
41   void CheckBarrier();
42   void ResumeClients(void);
43
44   struct client {
45     void* data;
46     LDResumeFn fn;
47     int refcount;
48   };
49   struct receiver {
50     void* data;
51     LDBarrierFn fn;
52     int on;
53   };
54
55   CkVec<client*> clients;
56   CkVec<receiver*> receivers;
57
58   int cur_refcount;
59   int max_client;
60   int client_count;
61   int max_receiver;
62   int at_count;
63   CmiBool on;
64
65   #if CMK_BIGSIM_CHARM
66   int first_free_client_slot;
67   #endif
68 };
69
70 class LBDB {
71 public:
72   LBDB();
73   ~LBDB() { }
74
75   void SetPeriod(double secs) {batsync.setPeriod(secs);}
76   double GetPeriod() {return batsync.getPeriod();}
77
78   void insert(LBOM *om);
79
80   LDOMHandle AddOM(LDOMid _userID, void* _userData, LDCallbacks _callbacks);
81   LDObjHandle AddObj(LDOMHandle _h, LDObjid _id, void *_userData,
82                      CmiBool _migratable);
83   void UnregisterObj(LDObjHandle _h);
84
85   void RegisteringObjects(LDOMHandle _h);
86   void DoneRegisteringObjects(LDOMHandle _h);
87
88   inline void LocalBarrierOn() 
89        { localBarrier.TurnOn();}
90   inline void LocalBarrierOff() 
91        { localBarrier.TurnOff();}
92
93   inline LBOM *LbOM(LDOMHandle h) 
94        { return oms[h.handle]; };
95   inline LBObj *LbObj(const LDObjHandle &h) const 
96        { return objs[h.handle]; };
97   inline LBObj *LbObjIdx(int h) const 
98        { return objs[h]; };
99   void DumpDatabase(void);
100
101   inline void TurnStatsOn(void) 
102        {statsAreOn = CmiTrue; machineUtil.StatsOn();}
103   inline void TurnStatsOff(void) 
104        {statsAreOn = CmiFalse;machineUtil.StatsOff();}
105   inline CmiBool StatsOn(void) const 
106        { return statsAreOn; };
107
108   void SetupPredictor(LDPredictModelFn on, LDPredictWindowFn onWin, LDPredictFn off, LDPredictModelFn change, void* data);
109   inline void TurnPredictorOn(void *model) {
110     if (predictCBFn!=NULL) predictCBFn->on(predictCBFn->data, model);
111     else CmiPrintf("Predictor not supported in this load balancer\n");
112   }
113   inline void TurnPredictorOn(void *model, int wind) {
114     if (predictCBFn!=NULL) predictCBFn->onWin(predictCBFn->data, model, wind);
115     else CmiPrintf("Predictor not supported in this load balancer\n");
116   }
117   inline void TurnPredictorOff(void) {
118     if (predictCBFn!=NULL) predictCBFn->off(predictCBFn->data);
119     else CmiPrintf("Predictor not supported in this load balancer\n");
120   }
121   /* the parameter model is really of class LBPredictorFunction in file LBDatabase.h */
122   inline void ChangePredictor(void *model) {
123     if (predictCBFn!=NULL) predictCBFn->change(predictCBFn->data, model);
124     else CmiPrintf("Predictor not supported in this load balancer");
125   }
126
127   void Send(const LDOMHandle &destOM, const LDObjid &destid, unsigned int bytes, int destObjProc);
128   void MulticastSend(const LDOMHandle &destOM, LDObjid *destids, int ndests, unsigned int bytes, int nMsgs);
129   int ObjDataCount();
130   void GetObjData(LDObjData *data);
131   inline int CommDataCount() { 
132     if (commTable)
133       return commTable->CommCount();
134     else return 0;
135   }
136   inline void GetCommData(LDCommData *data) 
137        { if (commTable) commTable->GetCommData(data); };
138
139   void MetaLBResumeWaitingChares(int lb_ideal_period);
140   void MetaLBCallLBOnChares();
141   int  Migrate(LDObjHandle h, int dest);
142   void Migrated(LDObjHandle h, int waitBarrier=1);
143   int  NotifyMigrated(LDMigratedFn fn, void* data);
144   void TurnOnNotifyMigrated(int handle)
145        { migrateCBList[handle]->on = 1; }
146   void TurnOffNotifyMigrated(int handle)
147        { migrateCBList[handle]->on = 0; }
148   void RemoveNotifyMigrated(int handle);
149
150   inline void TurnManualLBOn() 
151        { useBarrier = CmiFalse; }
152   inline void TurnManualLBOff() 
153        { useBarrier = CmiTrue; }
154
155   int AddStartLBFn(LDStartLBFn fn, void* data);
156   void TurnOnStartLBFn(int handle)
157        { startLBFnList[handle]->on = 1; }
158   void TurnOffStartLBFn(int handle)
159        { startLBFnList[handle]->on = 0; }
160   void RemoveStartLBFn(LDStartLBFn fn);
161   void StartLB();
162
163   int AddMigrationDoneFn(LDMigrationDoneFn fn, void* data);
164   void RemoveMigrationDoneFn(LDMigrationDoneFn fn);
165   void MigrationDone();
166
167   inline void IdleTime(LBRealType* walltime) 
168        { machineUtil.IdleTime(walltime); };
169   inline void TotalTime(LBRealType* walltime, LBRealType* cputime) 
170        { machineUtil.TotalTime(walltime,cputime); };
171   void BackgroundLoad(LBRealType* walltime, LBRealType* cputime);
172   void GetTime(LBRealType *total_walltime,LBRealType *total_cputime,
173                    LBRealType *idletime, LBRealType *bg_walltime, LBRealType *bg_cputime);
174   void ClearLoads(void);
175
176   /**
177     runningObj records the obj handler index so that load balancer
178     knows if an event(e.g. Send) is in an entry function or not.
179     An index is enough here because LDObjHandle can be retrieved from 
180     objs array. Copying LDObjHandle is expensive.
181   */
182   inline void SetRunningObj(const LDObjHandle &_h) 
183        { runningObj = _h.handle; obj_running = CmiTrue; };
184   inline const LDObjHandle &RunningObj() const 
185        { return objs[runningObj]->GetLDObjHandle(); };
186   inline void NoRunningObj() 
187        { obj_running = CmiFalse; };
188   inline CmiBool ObjIsRunning() const 
189        { return obj_running; };
190   
191   inline LDBarrierClient AddLocalBarrierClient(LDResumeFn fn, void* data) 
192        { return localBarrier.AddClient(fn,data); };
193   inline void RemoveLocalBarrierClient(LDBarrierClient h) 
194        { localBarrier.RemoveClient(h); };
195   inline LDBarrierReceiver AddLocalBarrierReceiver(LDBarrierFn fn, void* data) 
196        { return localBarrier.AddReceiver(fn,data); };
197   inline void RemoveLocalBarrierReceiver(LDBarrierReceiver h) 
198        { localBarrier.RemoveReceiver(h); };
199   inline void TurnOnBarrierReceiver(LDBarrierReceiver h) 
200        { localBarrier.TurnOnReceiver(h); };
201   inline void TurnOffBarrierReceiver(LDBarrierReceiver h) 
202        { localBarrier.TurnOffReceiver(h); };
203   inline void AtLocalBarrier(LDBarrierClient h) 
204        { 
205                         if(CmiMyPartition()==1)
206                                 CkPrintf("[%d] LBDBManager local barrier\n",CkMyPe());
207                    if (useBarrier) 
208                    localBarrier.AtBarrier(h); 
209            };
210   inline void ResumeClients() 
211        { localBarrier.ResumeClients(); };
212   inline void MeasuredObjTime(double wtime, double ctime) {
213     if (statsAreOn) {
214       obj_walltime += wtime;
215 #if CMK_LB_CPUTIMER
216       obj_cputime += ctime;
217 #endif
218     }
219   };
220
221   //This class controls the builtin-atsync frequency
222   class batsyncer {
223   private:
224     LBDB *db; //Enclosing LBDB object
225     double period;//Time (seconds) between builtin-atsyncs  
226     double nextT;
227     LDBarrierClient BH;//Handle for the builtin-atsync barrier 
228     static void gotoSync(void *bs);
229     static void resumeFromSync(void *bs);
230   public:
231     void init(LBDB *_db,double initPeriod);
232     void setPeriod(double p) {period=p;}
233     double getPeriod() {return period;}
234   };
235
236 private:
237   struct MigrateCB {
238     LDMigratedFn fn;
239     void* data;
240     int on;
241   };
242
243   struct StartLBCB {
244     LDStartLBFn fn;
245     void* data;
246     int on;
247   };
248
249   struct MigrationDoneCB {
250     LDMigrationDoneFn fn;
251     void* data;
252   };
253
254   struct PredictCB {
255     LDPredictModelFn on;
256     LDPredictWindowFn onWin;
257     LDPredictFn off;
258     LDPredictModelFn change;
259     void* data;
260   };
261
262   typedef CkVec<LBOM*> OMList;
263   typedef CkVec<LBObj*> ObjList;
264   typedef CkVec<MigrateCB*> MigrateCBList;
265   typedef CkVec<StartLBCB*> StartLBCBList;
266   typedef CkVec<MigrationDoneCB*> MigrationDoneCBList;
267
268   LBCommTable* commTable;
269   OMList oms;
270   int omCount;
271   int oms_registering;
272
273   ObjList objs;
274   int objCount;
275
276   CmiBool statsAreOn;
277   MigrateCBList migrateCBList;
278
279   MigrationDoneCBList migrationDoneCBList;
280
281   PredictCB* predictCBFn;
282
283   CmiBool obj_running;
284   int runningObj;               // index of the runningObj in ObjList
285
286   batsyncer batsync;
287
288   LocalBarrier localBarrier;    // local barrier to trigger LB automatically
289   CmiBool useBarrier;           // use barrier or not
290
291   LBMachineUtil machineUtil;
292   double obj_walltime;
293 #if CMK_LB_CPUTIMER
294   double obj_cputime;
295 #endif
296
297   StartLBCBList  startLBFnList;
298   int            startLBFn_count;
299 public:
300   int useMem();
301 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
302     int validObjHandle(LDObjHandle h ){
303             if(objCount == 0)
304                 return 0;
305             if(h.handle > objCount)
306                 return 0;
307             if(objs[h.handle] == NULL)
308                 return 0;
309
310             return 1;
311     }
312 #endif
313
314
315   int getObjCount() {return objCount;}
316   const ObjList& getObjs() {return objs;}
317
318
319
320 };
321
322 #endif
323
324 /*@}*/