2b21503c68a0463730f5092d0670e2bef0d03446
[charm.git] / src / ck-ldb / LBDBManager.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**
9  * \addtogroup CkLdb
10 */
11 /*@{*/
12
13 #ifndef LBDB_H
14 #define LBDB_H
15
16 #include "converse.h"
17 #include "lbdb.h"
18 #include "cklists.h"
19
20 #include "LBObj.h"
21 #include "LBOM.h"
22 #include "LBComm.h"
23 #include "LBMachineUtil.h"
24
25 class LocalBarrier {
26 friend class LBDB;
27 public:
28   LocalBarrier() { cur_refcount = 1; client_count = 0; max_client = 0;
29                    max_receiver= 0; at_count = 0; on = CmiFalse; 
30         #if CMK_BLUEGENE_CHARM
31         first_free_client_slot = 0;
32         #endif
33     };
34   ~LocalBarrier() { };
35
36   LDBarrierClient AddClient(LDResumeFn fn, void* data);
37   void RemoveClient(LDBarrierClient h);
38   LDBarrierReceiver AddReceiver(LDBarrierFn fn, void* data);
39   void RemoveReceiver(LDBarrierReceiver h);
40   void TurnOnReceiver(LDBarrierReceiver h);
41   void TurnOffReceiver(LDBarrierReceiver h);
42   void AtBarrier(LDBarrierClient h);
43   void TurnOn() { on = CmiTrue; CheckBarrier(); };
44   void TurnOff() { on = CmiFalse; };
45
46 private:
47   void CallReceivers(void);
48   void CheckBarrier();
49   void ResumeClients(void);
50
51   struct client {
52     void* data;
53     LDResumeFn fn;
54     int refcount;
55   };
56   struct receiver {
57     void* data;
58     LDBarrierFn fn;
59     int on;
60   };
61
62   CkVec<client*> clients;
63   CkVec<receiver*> receivers;
64
65   int cur_refcount;
66   int max_client;
67   int client_count;
68   int max_receiver;
69   int at_count;
70   CmiBool on;
71
72   #if CMK_BLUEGENE_CHARM
73   int first_free_client_slot;
74   #endif
75 };
76
77 class LBDB {
78 public:
79   LBDB();
80   ~LBDB() { }
81
82   void SetPeriod(double secs) {batsync.setPeriod(secs);}
83   double GetPeriod() {return batsync.getPeriod();}
84
85   void insert(LBOM *om);
86
87   LDOMHandle AddOM(LDOMid _userID, void* _userData, LDCallbacks _callbacks);
88   LDObjHandle AddObj(LDOMHandle _h, LDObjid _id, void *_userData,
89                      CmiBool _migratable);
90   void UnregisterObj(LDObjHandle _h);
91
92   void RegisteringObjects(LDOMHandle _h);
93   void DoneRegisteringObjects(LDOMHandle _h);
94
95   inline void LocalBarrierOn() 
96        { localBarrier.TurnOn();}
97   inline void LocalBarrierOff() 
98        { localBarrier.TurnOff();}
99
100   inline LBOM *LbOM(LDOMHandle h) 
101        { return oms[h.handle]; };
102   inline LBObj *LbObj(const LDObjHandle &h) const 
103        { return objs[h.handle]; };
104   inline LBObj *LbObjIdx(int h) const 
105        { return objs[h]; };
106   void DumpDatabase(void);
107
108   inline void TurnStatsOn(void) 
109        {statsAreOn = CmiTrue; machineUtil.StatsOn();}
110   inline void TurnStatsOff(void) 
111        {statsAreOn = CmiFalse;machineUtil.StatsOff();}
112   inline CmiBool StatsOn(void) const 
113        { return statsAreOn; };
114
115   void SetupPredictor(LDPredictModelFn on, LDPredictWindowFn onWin, LDPredictFn off, LDPredictModelFn change, void* data);
116   inline void TurnPredictorOn(void *model) {
117     if (predictCBFn!=NULL) predictCBFn->on(predictCBFn->data, model);
118     else CmiPrintf("Predictor not supported in this load balancer\n");
119   }
120   inline void TurnPredictorOn(void *model, int wind) {
121     if (predictCBFn!=NULL) predictCBFn->onWin(predictCBFn->data, model, wind);
122     else CmiPrintf("Predictor not supported in this load balancer\n");
123   }
124   inline void TurnPredictorOff(void) {
125     if (predictCBFn!=NULL) predictCBFn->off(predictCBFn->data);
126     else CmiPrintf("Predictor not supported in this load balancer\n");
127   }
128   /* the parameter model is really of class LBPredictorFunction in file LBDatabase.h */
129   inline void ChangePredictor(void *model) {
130     if (predictCBFn!=NULL) predictCBFn->change(predictCBFn->data, model);
131     else CmiPrintf("Predictor not supported in this load balancer");
132   }
133
134   void Send(const LDOMHandle &destOM, const LDObjid &destid, unsigned int bytes, int destObjProc);
135   void MulticastSend(const LDOMHandle &destOM, LDObjid *destids, int ndests, unsigned int bytes, int nMsgs);
136   int ObjDataCount();
137   void GetObjData(LDObjData *data);
138   inline int CommDataCount() { 
139     if (commTable)
140       return commTable->CommCount();
141     else return 0;
142   }
143   inline void GetCommData(LDCommData *data) 
144        { if (commTable) commTable->GetCommData(data); };
145
146   int  Migrate(LDObjHandle h, int dest);
147   void Migrated(LDObjHandle h, int waitBarrier=1);
148   int  NotifyMigrated(LDMigratedFn fn, void* data);
149   void TurnOnNotifyMigrated(int handle)
150        { migrateCBList[handle]->on = 1; }
151   void TurnOffNotifyMigrated(int handle)
152        { migrateCBList[handle]->on = 0; }
153   void RemoveNotifyMigrated(int handle);
154
155   inline void TurnManualLBOn() 
156        { useBarrier = CmiFalse; }
157   inline void TurnManualLBOff() 
158        { useBarrier = CmiTrue; }
159
160   int AddStartLBFn(LDStartLBFn fn, void* data);
161   void TurnOnStartLBFn(int handle)
162        { startLBFnList[handle]->on = 1; }
163   void TurnOffStartLBFn(int handle)
164        { startLBFnList[handle]->on = 0; }
165   void RemoveStartLBFn(LDStartLBFn fn);
166   void StartLB();
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     LDBarrierClient BH;//Handle for the builtin-atsync barrier 
223     static void gotoSync(void *bs);
224     static void resumeFromSync(void *bs);
225   public:
226     void init(LBDB *_db,double initPeriod);
227     void setPeriod(double p) {period=p;}
228     double getPeriod() {return period;}
229   };
230
231 private:
232   struct MigrateCB {
233     LDMigratedFn fn;
234     void* data;
235     int on;
236   };
237
238   struct StartLBCB {
239     LDStartLBFn fn;
240     void* data;
241     int on;
242   };
243
244   struct PredictCB {
245     LDPredictModelFn on;
246     LDPredictWindowFn onWin;
247     LDPredictFn off;
248     LDPredictModelFn change;
249     void* data;
250   };
251
252   typedef CkVec<LBOM*> OMList;
253   typedef CkVec<LBObj*> ObjList;
254   typedef CkVec<MigrateCB*> MigrateCBList;
255   typedef CkVec<StartLBCB*> StartLBCBList;
256
257   LBCommTable* commTable;
258   OMList oms;
259   int omCount;
260   int oms_registering;
261
262   ObjList objs;
263   int objCount;
264
265   CmiBool statsAreOn;
266   MigrateCBList migrateCBList;
267
268   PredictCB* predictCBFn;
269
270   CmiBool obj_running;
271   int runningObj;               // index of the runningObj in ObjList
272
273   batsyncer batsync;
274
275   LocalBarrier localBarrier;    // local barrier to trigger LB automatically
276   CmiBool useBarrier;           // use barrier or not
277
278   LBMachineUtil machineUtil;
279   double obj_walltime;
280 #if CMK_LB_CPUTIMER
281   double obj_cputime;
282 #endif
283
284   StartLBCBList  startLBFnList;
285   int            startLBFn_count;
286 public:
287   int useMem();
288 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
289     int validObjHandle(LDObjHandle h ){
290             if(objCount == 0)
291                 return 0;
292             if(h.handle > objCount)
293                 return 0;
294             if(objs[h.handle] == NULL)
295                 return 0;
296
297             return 1;
298     }
299 #endif
300
301
302   int getObjCount() {return objCount;}
303   const ObjList& getObjs() {return objs;}
304
305
306
307 };
308
309 #endif
310
311 /*@}*/