Merging
[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   
82
83   LDObjHandle AddObj(LDOMHandle _h, LDObjid _id, void *_userData,
84                      CmiBool _migratable);
85   void UnregisterObj(LDObjHandle _h);
86
87   void RegisteringObjects(LDOMHandle _h);
88   void DoneRegisteringObjects(LDOMHandle _h);
89
90   inline void LocalBarrierOn() 
91        { localBarrier.TurnOn();}
92   inline void LocalBarrierOff() 
93        { localBarrier.TurnOff();}
94
95   inline LBOM *LbOM(LDOMHandle h) 
96        { return oms[h.handle]; };
97   inline LBObj *LbObj(const LDObjHandle &h) const 
98        { return objs[h.handle]; };
99   inline LBObj *LbObjIdx(int h) const 
100        { return objs[h]; };
101   void DumpDatabase(void);
102
103   inline void TurnStatsOn(void) 
104        {statsAreOn = CmiTrue; machineUtil.StatsOn();}
105   inline void TurnStatsOff(void) 
106        {statsAreOn = CmiFalse;machineUtil.StatsOff();}
107   inline CmiBool StatsOn(void) const 
108        { return statsAreOn; };
109
110   void SetupPredictor(LDPredictModelFn on, LDPredictWindowFn onWin, LDPredictFn off, LDPredictModelFn change, void* data);
111   inline void TurnPredictorOn(void *model) {
112     if (predictCBFn!=NULL) predictCBFn->on(predictCBFn->data, model);
113     else CmiPrintf("Predictor not supported in this load balancer\n");
114   }
115   inline void TurnPredictorOn(void *model, int wind) {
116     if (predictCBFn!=NULL) predictCBFn->onWin(predictCBFn->data, model, wind);
117     else CmiPrintf("Predictor not supported in this load balancer\n");
118   }
119   inline void TurnPredictorOff(void) {
120     if (predictCBFn!=NULL) predictCBFn->off(predictCBFn->data);
121     else CmiPrintf("Predictor not supported in this load balancer\n");
122   }
123   /* the parameter model is really of class LBPredictorFunction in file LBDatabase.h */
124   inline void ChangePredictor(void *model) {
125     if (predictCBFn!=NULL) predictCBFn->change(predictCBFn->data, model);
126     else CmiPrintf("Predictor not supported in this load balancer");
127   }
128
129   void Send(const LDOMHandle &destOM, const LDObjid &destid, unsigned int bytes, int destObjProc);
130   void MulticastSend(const LDOMHandle &destOM, LDObjid *destids, int ndests, unsigned int bytes, int nMsgs);
131   int ObjDataCount();
132   void GetObjData(LDObjData *data);
133   inline int CommDataCount() { 
134     if (commTable)
135       return commTable->CommCount();
136     else return 0;
137   }
138   inline void GetCommData(LDCommData *data) 
139        { if (commTable) commTable->GetCommData(data); };
140
141   void AdaptResumeSync(int lb_ideal_period);
142   int  Migrate(LDObjHandle h, int dest);
143   void Migrated(LDObjHandle h, int waitBarrier=1);
144   int  NotifyMigrated(LDMigratedFn fn, void* data);
145   void TurnOnNotifyMigrated(int handle)
146        { migrateCBList[handle]->on = 1; }
147   void TurnOffNotifyMigrated(int handle)
148        { migrateCBList[handle]->on = 0; }
149   void RemoveNotifyMigrated(int handle);
150
151   inline void TurnManualLBOn() 
152        { useBarrier = CmiFalse; }
153   inline void TurnManualLBOff() 
154        { useBarrier = CmiTrue; }
155
156   int AddStartLBFn(LDStartLBFn fn, void* data);
157   void TurnOnStartLBFn(int handle)
158        { startLBFnList[handle]->on = 1; }
159   void TurnOffStartLBFn(int handle)
160        { startLBFnList[handle]->on = 0; }
161   void RemoveStartLBFn(LDStartLBFn fn);
162   void StartLB();
163
164   int AddMigrationDoneFn(LDMigrationDoneFn fn, void* data);
165   void RemoveMigrationDoneFn(LDMigrationDoneFn fn);
166   void MigrationDone();
167
168   inline void IdleTime(LBRealType* walltime) 
169        { machineUtil.IdleTime(walltime); };
170   inline void TotalTime(LBRealType* walltime, LBRealType* cputime) 
171        { machineUtil.TotalTime(walltime,cputime); };
172   void BackgroundLoad(LBRealType* walltime, LBRealType* cputime);
173   void GetTime(LBRealType *total_walltime,LBRealType *total_cputime,
174                    LBRealType *idletime, LBRealType *bg_walltime, LBRealType *bg_cputime);
175   void ClearLoads(void);
176
177   /**
178     runningObj records the obj handler index so that load balancer
179     knows if an event(e.g. Send) is in an entry function or not.
180     An index is enough here because LDObjHandle can be retrieved from 
181     objs array. Copying LDObjHandle is expensive.
182   */
183   inline void SetRunningObj(const LDObjHandle &_h) 
184        { runningObj = _h.handle; obj_running = CmiTrue; };
185   inline const LDObjHandle &RunningObj() const 
186        { return objs[runningObj]->GetLDObjHandle(); };
187   inline void NoRunningObj() 
188        { obj_running = CmiFalse; };
189   inline CmiBool ObjIsRunning() const 
190        { return obj_running; };
191   
192   inline LDBarrierClient AddLocalBarrierClient(LDResumeFn fn, void* data) 
193        { return localBarrier.AddClient(fn,data); };
194   inline void RemoveLocalBarrierClient(LDBarrierClient h) 
195        { localBarrier.RemoveClient(h); };
196   inline LDBarrierReceiver AddLocalBarrierReceiver(LDBarrierFn fn, void* data) 
197        { return localBarrier.AddReceiver(fn,data); };
198   inline void RemoveLocalBarrierReceiver(LDBarrierReceiver h) 
199        { localBarrier.RemoveReceiver(h); };
200   inline void TurnOnBarrierReceiver(LDBarrierReceiver h) 
201        { localBarrier.TurnOnReceiver(h); };
202   inline void TurnOffBarrierReceiver(LDBarrierReceiver h) 
203        { localBarrier.TurnOffReceiver(h); };
204   inline void AtLocalBarrier(LDBarrierClient h) 
205        { if (useBarrier) localBarrier.AtBarrier(h); };
206   inline void ResumeClients() 
207        { localBarrier.ResumeClients(); };
208   inline void MeasuredObjTime(double wtime, double ctime) {
209     if (statsAreOn) {
210       obj_walltime += wtime;
211 #if CMK_LB_CPUTIMER
212       obj_cputime += ctime;
213 #endif
214     }
215   };
216
217   //This class controls the builtin-atsync frequency
218   class batsyncer {
219   private:
220     LBDB *db; //Enclosing LBDB object
221     double period;//Time (seconds) between builtin-atsyncs  
222     double nextT;
223     LDBarrierClient BH;//Handle for the builtin-atsync barrier 
224     static void gotoSync(void *bs);
225     static void resumeFromSync(void *bs);
226   public:
227     void init(LBDB *_db,double initPeriod);
228     void setPeriod(double p) {period=p;}
229     double getPeriod() {return period;}
230   };
231
232 private:
233   struct MigrateCB {
234     LDMigratedFn fn;
235     void* data;
236     int on;
237   };
238
239   struct StartLBCB {
240     LDStartLBFn fn;
241     void* data;
242     int on;
243   };
244
245   struct MigrationDoneCB {
246     LDMigrationDoneFn fn;
247     void* data;
248   };
249
250   struct PredictCB {
251     LDPredictModelFn on;
252     LDPredictWindowFn onWin;
253     LDPredictFn off;
254     LDPredictModelFn change;
255     void* data;
256   };
257
258   typedef CkVec<LBOM*> OMList;
259   typedef CkVec<LBObj*> ObjList;
260   typedef CkVec<MigrateCB*> MigrateCBList;
261   typedef CkVec<StartLBCB*> StartLBCBList;
262   typedef CkVec<MigrationDoneCB*> MigrationDoneCBList;
263
264   LBCommTable* commTable;
265   OMList oms;
266   int omCount;
267   int oms_registering;
268
269   ObjList objs;
270   int objCount;
271
272   CmiBool statsAreOn;
273   MigrateCBList migrateCBList;
274
275   MigrationDoneCBList migrationDoneCBList;
276
277   PredictCB* predictCBFn;
278
279   CmiBool obj_running;
280   int runningObj;               // index of the runningObj in ObjList
281
282   batsyncer batsync;
283
284   LocalBarrier localBarrier;    // local barrier to trigger LB automatically
285   CmiBool useBarrier;           // use barrier or not
286
287   LBMachineUtil machineUtil;
288   double obj_walltime;
289 #if CMK_LB_CPUTIMER
290   double obj_cputime;
291 #endif
292
293   StartLBCBList  startLBFnList;
294   int            startLBFn_count;
295 public:
296   int useMem();
297 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
298     int validObjHandle(LDObjHandle h ){
299             if(objCount == 0)
300                 return 0;
301             if(h.handle > objCount)
302                 return 0;
303             if(objs[h.handle] == NULL)
304                 return 0;
305
306             return 1;
307     }
308 #endif
309
310
311   int getObjCount() {return objCount;}
312   const ObjList& getObjs() {return objs;}
313
314
315
316 };
317
318 #endif
319
320 /*@}*/