00001 
00005 
00006 #ifndef LBDB_H
00007 #define LBDB_H
00008 
00009 #include "converse.h"
00010 #include "lbdb.h"
00011 #include "cklists.h"
00012 
00013 #include "LBObj.h"
00014 #include "LBOM.h"
00015 #include "LBComm.h"
00016 #include "LBMachineUtil.h"
00017 
00018 class client;
00019 class receiver;
00020 
00021 class LocalBarrier {
00022 friend class LBDB;
00023 public:
00024   LocalBarrier() { cur_refcount = 1; client_count = 0;
00025                    max_receiver= 0; at_count = 0; on = false; 
00026     #if CMK_BIGSIM_CHARM
00027     first_free_client_slot = 0;
00028     #endif
00029     };
00030   ~LocalBarrier() { };
00031 
00032   LDBarrierClient AddClient(LDResumeFn fn, void* data);
00033   void RemoveClient(LDBarrierClient h);
00034   LDBarrierReceiver AddReceiver(LDBarrierFn fn, void* data);
00035   void RemoveReceiver(LDBarrierReceiver h);
00036   void TurnOnReceiver(LDBarrierReceiver h);
00037   void TurnOffReceiver(LDBarrierReceiver h);
00038   void AtBarrier(LDBarrierClient h);
00039   void DecreaseBarrier(LDBarrierClient h, int c);
00040   void TurnOn() { on = true; CheckBarrier(); };
00041   void TurnOff() { on = false; };
00042 
00043 private:
00044   void CallReceivers(void);
00045   void CheckBarrier();
00046   void ResumeClients(void);
00047 
00048   std::list<client*> clients;
00049   std::list<receiver*> receivers;
00050 
00051   int cur_refcount;
00052   int client_count;
00053   int max_receiver;
00054   int at_count;
00055   bool on;
00056 
00057   #if CMK_BIGSIM_CHARM
00058   int first_free_client_slot;
00059   #endif
00060 };
00061 
00062 class LBDB {
00063 public:
00064   LBDB();
00065   ~LBDB() { }
00066 
00067   void SetPeriod(double secs) {batsync.setPeriod(secs);}
00068   double GetPeriod() {return batsync.getPeriod();}
00069 
00070   void insert(LBOM *om);
00071 
00072   LDOMHandle AddOM(LDOMid _userID, void* _userData, LDCallbacks _callbacks);
00073   void RemoveOM(LDOMHandle om);
00074 
00075   LDObjHandle AddObj(LDOMHandle _h, CmiUInt8 _id, void *_userData,
00076              bool _migratable);
00077   void UnregisterObj(LDObjHandle _h);
00078 
00079   void RegisteringObjects(LDOMHandle _h);
00080   void DoneRegisteringObjects(LDOMHandle _h);
00081 
00082   inline void LocalBarrierOn() 
00083        { localBarrier.TurnOn();}
00084   inline void LocalBarrierOff() 
00085        { localBarrier.TurnOff();}
00086 
00087   inline LBOM *LbOM(LDOMHandle h) 
00088        { return oms[h.handle]; };
00089   inline LBObj *LbObj(const LDObjHandle &h) const 
00090        { return objs[h.handle].obj; };
00091   inline LBObj *LbObjIdx(int h) const 
00092        { return objs[h].obj; };
00093   void DumpDatabase(void);
00094 
00095   inline void TurnStatsOn(void) 
00096        {statsAreOn = true; machineUtil.StatsOn();}
00097   inline void TurnStatsOff(void) 
00098        {statsAreOn = false;machineUtil.StatsOff();}
00099   inline bool StatsOn(void) const 
00100        { return statsAreOn; };
00101 
00102   void SetupPredictor(LDPredictModelFn on, LDPredictWindowFn onWin, LDPredictFn off, LDPredictModelFn change, void* data);
00103   inline void TurnPredictorOn(void *model) {
00104     if (predictCBFn!=NULL) predictCBFn->on(predictCBFn->data, model);
00105     else CmiPrintf("Predictor not supported in this load balancer\n");
00106   }
00107   inline void TurnPredictorOn(void *model, int wind) {
00108     if (predictCBFn!=NULL) predictCBFn->onWin(predictCBFn->data, model, wind);
00109     else CmiPrintf("Predictor not supported in this load balancer\n");
00110   }
00111   inline void TurnPredictorOff(void) {
00112     if (predictCBFn!=NULL) predictCBFn->off(predictCBFn->data);
00113     else CmiPrintf("Predictor not supported in this load balancer\n");
00114   }
00115   
00116   inline void ChangePredictor(void *model) {
00117     if (predictCBFn!=NULL) predictCBFn->change(predictCBFn->data, model);
00118     else CmiPrintf("Predictor not supported in this load balancer");
00119   }
00120 
00121   void Send(const LDOMHandle &destOM, const CmiUInt8 &destid, unsigned int bytes, int destObjProc);
00122   void MulticastSend(const LDOMHandle &destOM, CmiUInt8 *destids, int ndests, unsigned int bytes, int nMsgs);
00123   int ObjDataCount();
00124   void GetObjData(LDObjData *data);
00125   inline int CommDataCount() { 
00126     if (commTable)
00127       return commTable->CommCount();
00128     else return 0;
00129   }
00130   inline void GetCommData(LDCommData *data) 
00131        { if (commTable) commTable->GetCommData(data); };
00132 
00133   inline void GetCommInfo(int& bytes, int& msgs, int& withinbytes, int& acrossbytes, int& num_nghbors, int& hops, int& hopbytes) {
00134     if (commTable)
00135       commTable->GetCommInfo(bytes, msgs, withinbytes, acrossbytes, num_nghbors, hops, hopbytes);
00136   };
00137 
00138   void MetaLBResumeWaitingChares(int lb_ideal_period);
00139   void MetaLBCallLBOnChares();
00140   int  Migrate(LDObjHandle h, int dest);
00141   void Migrated(LDObjHandle h, int waitBarrier=1);
00142   int  NotifyMigrated(LDMigratedFn fn, void* data);
00143   void TurnOnNotifyMigrated(int handle)
00144        { migrateCBList[handle]->on = 1; }
00145   void TurnOffNotifyMigrated(int handle)
00146        { migrateCBList[handle]->on = 0; }
00147   void RemoveNotifyMigrated(int handle);
00148 
00149   inline void TurnManualLBOn() 
00150        { useBarrier = false; LocalBarrierOff(); }
00151   inline void TurnManualLBOff() 
00152        { useBarrier = true; if (oms_registering == 0) LocalBarrierOn(); }
00153 
00154   int AddStartLBFn(LDStartLBFn fn, void* data);
00155   void TurnOnStartLBFn(int handle)
00156        { startLBFnList[handle]->on = 1; }
00157   void TurnOffStartLBFn(int handle)
00158        { startLBFnList[handle]->on = 0; }
00159   void RemoveStartLBFn(LDStartLBFn fn);
00160   void StartLB();
00161 
00162   int AddMigrationDoneFn(LDMigrationDoneFn fn, void* data);
00163   void RemoveMigrationDoneFn(LDMigrationDoneFn fn);
00164   void MigrationDone();
00165 
00166   inline void IdleTime(LBRealType* walltime) 
00167        { machineUtil.IdleTime(walltime); };
00168   inline void TotalTime(LBRealType* walltime, LBRealType* cputime) 
00169        { machineUtil.TotalTime(walltime,cputime); };
00170   void BackgroundLoad(LBRealType* walltime, LBRealType* cputime);
00171   void GetTime(LBRealType *total_walltime,LBRealType *total_cputime,
00172                    LBRealType *idletime, LBRealType *bg_walltime, LBRealType *bg_cputime);
00173   void ClearLoads(void);
00174 
00181   inline void SetRunningObj(const LDObjHandle &_h) 
00182        { runningObj = _h.handle; obj_running = true; };
00183   inline const LDObjHandle &RunningObj() const 
00184        { return objs[runningObj].obj->GetLDObjHandle(); };
00185   inline void NoRunningObj() 
00186        { obj_running = false; };
00187   inline bool ObjIsRunning() const 
00188        { return obj_running; };
00189   
00190   inline LDBarrierClient AddLocalBarrierClient(LDResumeFn fn, void* data) 
00191        { return localBarrier.AddClient(fn,data); };
00192   inline void RemoveLocalBarrierClient(LDBarrierClient h) 
00193        { localBarrier.RemoveClient(h); };
00194   inline LDBarrierReceiver AddLocalBarrierReceiver(LDBarrierFn fn, void* data) 
00195        { return localBarrier.AddReceiver(fn,data); };
00196   inline void RemoveLocalBarrierReceiver(LDBarrierReceiver h) 
00197        { localBarrier.RemoveReceiver(h); };
00198   inline void TurnOnBarrierReceiver(LDBarrierReceiver h) 
00199        { localBarrier.TurnOnReceiver(h); };
00200   inline void TurnOffBarrierReceiver(LDBarrierReceiver h) 
00201        { localBarrier.TurnOffReceiver(h); };
00202   inline void AtLocalBarrier(LDBarrierClient h) 
00203        { localBarrier.AtBarrier(h); };
00204   inline void DecreaseLocalBarrier(LDBarrierClient h, int c) 
00205        { localBarrier.DecreaseBarrier(h, c); };
00206   inline void ResumeClients() 
00207        { localBarrier.ResumeClients(); };
00208   inline void MeasuredObjTime(double wtime, double ctime) {
00209     (void)ctime;
00210     if (statsAreOn) {
00211       obj_walltime += wtime;
00212 #if CMK_LB_CPUTIMER
00213       obj_cputime += ctime;
00214 #endif
00215     }
00216   };
00217 
00218   
00219   class batsyncer {
00220   private:
00221     LBDB *db; 
00222     double period;
00223     double nextT;
00224     LDBarrierClient BH;
00225     bool gotoSyncCalled;
00226     static void gotoSync(void *bs);
00227     static void resumeFromSync(void *bs);
00228   public:
00229     void init(LBDB *_db,double initPeriod);
00230     void setPeriod(double p) {period=p;}
00231     double getPeriod() {return period;}
00232   };
00233 
00234 private:
00235   struct MigrateCB {
00236     LDMigratedFn fn;
00237     void* data;
00238     int on;
00239   };
00240 
00241   struct StartLBCB {
00242     LDStartLBFn fn;
00243     void* data;
00244     int on;
00245   };
00246 
00247   struct MigrationDoneCB {
00248     LDMigrationDoneFn fn;
00249     void* data;
00250   };
00251 
00252   struct PredictCB {
00253     LDPredictModelFn on;
00254     LDPredictWindowFn onWin;
00255     LDPredictFn off;
00256     LDPredictModelFn change;
00257     void* data;
00258   };
00259 
00260   struct LBObjEntry {
00261     LBObj* obj;
00262     LDObjIndex next;
00263 
00264     LBObjEntry(LBObj* obj, LDObjIndex next = -1) : obj(obj), next(next) {}
00265   };
00266 
00267   typedef CkVec<LBOM*> OMList;
00268   typedef std::vector<LBObjEntry> ObjList;
00269   typedef CkVec<MigrateCB*> MigrateCBList;
00270   typedef CkVec<StartLBCB*> StartLBCBList;
00271   typedef CkVec<MigrationDoneCB*> MigrationDoneCBList;
00272 
00273   LBCommTable* commTable;
00274   OMList oms;
00275   int omCount;
00276   int oms_registering;
00277 
00278   LDObjIndex objsEmptyHead;
00279   ObjList objs;
00280 
00281   bool statsAreOn;
00282   MigrateCBList migrateCBList;
00283 
00284   MigrationDoneCBList migrationDoneCBList;
00285 
00286   PredictCB* predictCBFn;
00287 
00288   bool obj_running;
00289   int runningObj;       
00290 
00291   batsyncer batsync;
00292 
00293   LocalBarrier localBarrier;    
00294   bool useBarrier;           
00295 
00296   LBMachineUtil machineUtil;
00297   double obj_walltime;
00298 #if CMK_LB_CPUTIMER
00299   double obj_cputime;
00300 #endif
00301 
00302   StartLBCBList  startLBFnList;
00303   int            startLBFn_count;
00304 public:
00305   int useMem();
00306 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00307     int validObjHandle(LDObjHandle h ){
00308             if(h.handle >= objs.size())
00309                 return 0;
00310             if(objs[h.handle].obj == NULL)
00311                 return 0;
00312 
00313             return 1;
00314     }
00315 #endif
00316 
00317 
00318   const ObjList& getObjs() {return objs;}
00319 
00320 
00321 
00322 };
00323 
00324 #endif
00325