Merge branch 'charm' of charmgit:charm into charm
[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   int  Migrate(LDObjHandle h, int dest);
140   void Migrated(LDObjHandle h, int waitBarrier=1);
141   int  NotifyMigrated(LDMigratedFn fn, void* data);
142   void TurnOnNotifyMigrated(int handle)
143        { migrateCBList[handle]->on = 1; }
144   void TurnOffNotifyMigrated(int handle)
145        { migrateCBList[handle]->on = 0; }
146   void RemoveNotifyMigrated(int handle);
147
148   inline void TurnManualLBOn() 
149        { useBarrier = CmiFalse; }
150   inline void TurnManualLBOff() 
151        { useBarrier = CmiTrue; }
152
153   int AddStartLBFn(LDStartLBFn fn, void* data);
154   void TurnOnStartLBFn(int handle)
155        { startLBFnList[handle]->on = 1; }
156   void TurnOffStartLBFn(int handle)
157        { startLBFnList[handle]->on = 0; }
158   void RemoveStartLBFn(LDStartLBFn fn);
159   void StartLB();
160
161   int AddMigrationDoneFn(LDMigrationDoneFn fn, void* data);
162   void RemoveMigrationDoneFn(LDMigrationDoneFn fn);
163   void MigrationDone();
164
165   inline void IdleTime(LBRealType* walltime) 
166        { machineUtil.IdleTime(walltime); };
167   inline void TotalTime(LBRealType* walltime, LBRealType* cputime) 
168        { machineUtil.TotalTime(walltime,cputime); };
169   void BackgroundLoad(LBRealType* walltime, LBRealType* cputime);
170   void GetTime(LBRealType *total_walltime,LBRealType *total_cputime,
171                    LBRealType *idletime, LBRealType *bg_walltime, LBRealType *bg_cputime);
172   void ClearLoads(void);
173
174   /**
175     runningObj records the obj handler index so that load balancer
176     knows if an event(e.g. Send) is in an entry function or not.
177     An index is enough here because LDObjHandle can be retrieved from 
178     objs array. Copying LDObjHandle is expensive.
179   */
180   inline void SetRunningObj(const LDObjHandle &_h) 
181        { runningObj = _h.handle; obj_running = CmiTrue; };
182   inline const LDObjHandle &RunningObj() const 
183        { return objs[runningObj]->GetLDObjHandle(); };
184   inline void NoRunningObj() 
185        { obj_running = CmiFalse; };
186   inline CmiBool ObjIsRunning() const 
187        { return obj_running; };
188   
189   inline LDBarrierClient AddLocalBarrierClient(LDResumeFn fn, void* data) 
190        { return localBarrier.AddClient(fn,data); };
191   inline void RemoveLocalBarrierClient(LDBarrierClient h) 
192        { localBarrier.RemoveClient(h); };
193   inline LDBarrierReceiver AddLocalBarrierReceiver(LDBarrierFn fn, void* data) 
194        { return localBarrier.AddReceiver(fn,data); };
195   inline void RemoveLocalBarrierReceiver(LDBarrierReceiver h) 
196        { localBarrier.RemoveReceiver(h); };
197   inline void TurnOnBarrierReceiver(LDBarrierReceiver h) 
198        { localBarrier.TurnOnReceiver(h); };
199   inline void TurnOffBarrierReceiver(LDBarrierReceiver h) 
200        { localBarrier.TurnOffReceiver(h); };
201   inline void AtLocalBarrier(LDBarrierClient h) 
202        { if (useBarrier) localBarrier.AtBarrier(h); };
203   inline void ResumeClients() 
204        { localBarrier.ResumeClients(); };
205   inline void MeasuredObjTime(double wtime, double ctime) {
206     if (statsAreOn) {
207       obj_walltime += wtime;
208 #if CMK_LB_CPUTIMER
209       obj_cputime += ctime;
210 #endif
211     }
212   };
213
214   //This class controls the builtin-atsync frequency
215   class batsyncer {
216   private:
217     LBDB *db; //Enclosing LBDB object
218     double period;//Time (seconds) between builtin-atsyncs  
219     double nextT;
220     LDBarrierClient BH;//Handle for the builtin-atsync barrier 
221     static void gotoSync(void *bs);
222     static void resumeFromSync(void *bs);
223   public:
224     void init(LBDB *_db,double initPeriod);
225     void setPeriod(double p) {period=p;}
226     double getPeriod() {return period;}
227   };
228
229 private:
230   struct MigrateCB {
231     LDMigratedFn fn;
232     void* data;
233     int on;
234   };
235
236   struct StartLBCB {
237     LDStartLBFn fn;
238     void* data;
239     int on;
240   };
241
242   struct MigrationDoneCB {
243     LDMigrationDoneFn fn;
244     void* data;
245   };
246
247   struct PredictCB {
248     LDPredictModelFn on;
249     LDPredictWindowFn onWin;
250     LDPredictFn off;
251     LDPredictModelFn change;
252     void* data;
253   };
254
255   typedef CkVec<LBOM*> OMList;
256   typedef CkVec<LBObj*> ObjList;
257   typedef CkVec<MigrateCB*> MigrateCBList;
258   typedef CkVec<StartLBCB*> StartLBCBList;
259   typedef CkVec<MigrationDoneCB*> MigrationDoneCBList;
260
261   LBCommTable* commTable;
262   OMList oms;
263   int omCount;
264   int oms_registering;
265
266   ObjList objs;
267   int objCount;
268
269   CmiBool statsAreOn;
270   MigrateCBList migrateCBList;
271
272   MigrationDoneCBList migrationDoneCBList;
273
274   PredictCB* predictCBFn;
275
276   CmiBool obj_running;
277   int runningObj;               // index of the runningObj in ObjList
278
279   batsyncer batsync;
280
281   LocalBarrier localBarrier;    // local barrier to trigger LB automatically
282   CmiBool useBarrier;           // use barrier or not
283
284   LBMachineUtil machineUtil;
285   double obj_walltime;
286 #if CMK_LB_CPUTIMER
287   double obj_cputime;
288 #endif
289
290   StartLBCBList  startLBFnList;
291   int            startLBFn_count;
292 public:
293   int useMem();
294 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
295     int validObjHandle(LDObjHandle h ){
296             if(objCount == 0)
297                 return 0;
298             if(h.handle > objCount)
299                 return 0;
300             if(objs[h.handle] == NULL)
301                 return 0;
302
303             return 1;
304     }
305 #endif
306
307
308   int getObjCount() {return objCount;}
309   const ObjList& getObjs() {return objs;}
310
311
312
313 };
314
315 #endif
316
317 /*@}*/