8995c39b844cb256af2d1a00fe80a12c02e32fd0
[charm.git] / src / ck-core / cklocation.h
1 /*
2 Location manager: keeps track of an indexed set of migratable
3 objects.  Used by the array manager to locate array elements,
4 interact with the load balancer, and perform migrations.
5
6 Does not handle reductions (see ckreduction.h), broadcasts,
7 array proxies, or the details of element creation (see ckarray.h).
8 */
9 #ifndef __CKLOCATION_H
10 #define __CKLOCATION_H
11
12 /*********************** Array Messages ************************/
13 class CkArrayMessage : public CkMessage {
14 public:
15   //These routines are implementation utilities
16   CkArrayIndex &array_index(void);
17   unsigned short &array_ep(void);
18   unsigned short &array_ep_bcast(void);
19   unsigned char &array_hops(void);
20   unsigned int array_getSrcPe(void);
21   unsigned int array_ifNotThere(void);
22   void array_setIfNotThere(unsigned int);
23   
24   //This allows us to delete bare CkArrayMessages
25   void operator delete(void *p){CkFreeMsg(p);}
26 };
27
28 /* Utility */
29 //#if CMK_LBDB_ON
30 #include "LBDatabase.h"
31 class LBDatabase;
32 //#endif
33
34 //Forward declarations
35 class CkArray;
36 class ArrayElement;
37 //What to do if an entry method is invoked on
38 // an array element that does not (yet) exist:
39 typedef enum {
40         CkArray_IfNotThere_buffer=0, //Wait for it to be created
41         CkArray_IfNotThere_createhere=1, //Make it on sending Pe
42         CkArray_IfNotThere_createhome=2 //Make it on (a) home Pe
43 } CkArray_IfNotThere;
44
45 /// How to do a message delivery:
46 typedef enum {
47         CkDeliver_queue=0, //Deliver via the scheduler's queue
48         CkDeliver_inline=1  //Deliver via a regular call
49 } CkDeliver_t;
50
51 #include "CkLocation.decl.h"
52
53 /************************** Array Messages ****************************/
54 /**
55  *  This is the message type used to actually send a migrating array element.
56  */
57
58 class CkArrayElementMigrateMessage : public CMessage_CkArrayElementMigrateMessage {
59 public:
60         CkArrayIndex idx; // Array index that is migrating
61         int ignoreArrival;   // if to inform LB of arrival
62         int length;//Size in bytes of the packed data
63 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
64         CkGroupID gid; //gid of location manager
65 #endif
66         CmiBool bounced;
67         double* packData;
68 };
69
70 /******************* Map object ******************/
71
72 extern CkGroupID _defaultArrayMapID;
73 extern CkGroupID _fastArrayMapID;
74 class CkLocMgr;
75 class CkArrMgr;
76
77 /**
78 \addtogroup CkArray
79 */
80 /*@{*/
81
82 /** The "map" is used by the array manager to map an array index to 
83  * a home processor number.
84  */
85 class CkArrayMap : public IrrGroup // : public CkGroupReadyCallback
86 {
87 public:
88   CkArrayMap(void);
89   CkArrayMap(CkMigrateMessage *m): IrrGroup(m) {}
90   virtual ~CkArrayMap();
91   virtual int registerArray(CkArrayIndex& numElements,CkArrayID aid);
92   virtual void populateInitial(int arrayHdl,CkArrayIndex& numElements,void *ctorMsg,CkArrMgr *mgr);
93   virtual int procNum(int arrayHdl,const CkArrayIndex &element) =0;
94   virtual int homePe(int arrayHdl,const CkArrayIndex &element)
95              { return procNum(arrayHdl, element); }
96 //  virtual void pup(PUP::er &p) { CkGroupReadyCallback::pup(p); }
97 };
98 /*@}*/
99
100 /**
101 \addtogroup CkArrayImpl
102 \brief Migratable Chare Arrays: Implementation classes.
103 */
104 /*@{*/
105 static inline CkGroupID CkCreatePropMap(void)
106 {
107   return CProxy_PropMap::ckNew();
108 }
109
110 extern void _propMapInit(void);
111 extern void _CkMigratable_initInfoInit(void);
112
113
114 /*************************** CkLocRec ******************************/
115 class CkArray;//Array manager
116 class CkLocMgr;//Location manager
117 class CkMigratable;//Migratable object
118
119 /**
120  * A CkLocRec is our local representation of an array element.
121  * The location manager's main hashtable maps array indices to
122  * CkLocRec *'s.
123  */
124 class CkLocRec {
125 protected:
126   CkLocMgr *myLocMgr;
127   //int lastAccess;//Age when last accessed. Removed since unused and colliding with a inheriting class, Filippo
128   //Called when we discover we are obsolete before we delete ourselves
129   virtual void weAreObsolete(const CkArrayIndex &idx);
130 public:
131   CkLocRec(CkLocMgr *mgr) :myLocMgr(mgr) { }
132   virtual ~CkLocRec();
133   inline CkLocMgr *getLocMgr(void) const {return myLocMgr;}
134
135   /// Return the type of this ArrayRec:
136   typedef enum {
137     base=0,//Base class (invalid type)
138     local,//Array element that lives on this Pe
139     remote,//Array element that lives on some other Pe
140     buffering,//Array element that was just created
141     dead//Deleted element (for debugging)
142   } RecType;
143   virtual RecType type(void)=0;
144   
145   /// Accept a message for this element
146   virtual CmiBool deliver(CkArrayMessage *m,CkDeliver_t type,int opts=0)=0;
147   
148   /// This is called when this ArrayRec is about to be replaced.
149   /// It is only used to deliver buffered element messages.
150   virtual void beenReplaced(void);
151   
152   /// Return if this rec is now obsolete
153   virtual CmiBool isObsolete(int nSprings,const CkArrayIndex &idx)=0; 
154
155   /// Return the represented array element; or NULL if there is none
156   virtual CkMigratable *lookupElement(CkArrayID aid);
157
158   /// Return the last known processor; or -1 if none
159   virtual int lookupProcessor(void);
160 };
161
162 /**
163  * Represents a local array element.
164  */
165 class CkLocRec_local : public CkLocRec {
166   CkArrayIndex idx;/// Element's array index
167   int localIdx; /// Local index (into array manager's element lists)
168   CmiBool running; /// True when inside a startTiming/stopTiming pair
169   CmiBool *deletedMarker; /// Set this if we're deleted during processing
170   CkQ<CkArrayMessage *> halfCreated; /// Stores messages for nonexistent siblings of existing elements
171 public:
172   //Creation and Destruction:
173   CkLocRec_local(CkLocMgr *mgr,CmiBool fromMigration,CmiBool ignoreArrival,
174         const CkArrayIndex &idx_,int localIdx_);
175   void migrateMe(int toPe); //Leave this processor
176   void destroy(void); //User called destructor
177   virtual ~CkLocRec_local();
178
179   /// A new element has been added to this index
180   void addedElement(void);
181
182   /**
183    *  Accept a message for this element.
184    *  Returns false if the element died during the receive.
185    */
186   virtual CmiBool deliver(CkArrayMessage *m,CkDeliver_t type,int opts=0);
187
188   /** Invoke the given entry method on this element.
189    *   Returns false if the element died during the receive.
190    *   If doFree is true, the message is freed after send;
191    *    if false, the message can be reused.
192    */
193   CmiBool invokeEntry(CkMigratable *obj,void *msg,int idx,CmiBool doFree);
194
195   virtual RecType type(void);
196   virtual CmiBool isObsolete(int nSprings,const CkArrayIndex &idx);
197
198 #if CMK_LBDB_ON  //For load balancing:
199   /// Control the load balancer:
200   void startTiming(int ignore_running=0);
201   void stopTiming(int ignore_running=0);
202   void setObjTime(double cputime);
203   double getObjTime();
204 #else
205   inline void startTiming(int ignore_running=0) {  }
206   inline void stopTiming(int ignore_running=0) { }
207 #endif
208   inline int getLocalIndex(void) const {return localIdx;}
209   inline const CkArrayIndex &getIndex(void) const {return idx;}
210   virtual CkMigratable *lookupElement(CkArrayID aid);
211   virtual int lookupProcessor(void);
212
213 #if CMK_LBDB_ON
214 public:
215   inline LBDatabase *getLBDB(void) const {return the_lbdb;}
216   inline LDObjHandle getLdHandle() const{return ldHandle;}
217   static void staticMigrate(LDObjHandle h, int dest);
218   void recvMigrate(int dest);
219   void setMigratable(int migratable);   /// set migratable
220   void AsyncMigrate(CmiBool use);
221   CmiBool isAsyncMigrate()   { return asyncMigrate; }
222   void ReadyMigrate(CmiBool ready) { readyMigrate = ready; } ///called from user
223   int  isReadyMigrate() { return readyMigrate; }
224   CmiBool checkBufferedMigration();     // check and execute pending migration
225   int   MigrateToPe();
226 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
227         void Migrated();
228 #endif
229   inline void setMeasure(CmiBool status) { enable_measure = status; }
230 private:
231   LBDatabase *the_lbdb;
232   LDObjHandle ldHandle;
233   CmiBool  asyncMigrate;  /// if readyMove is inited
234   CmiBool  readyMigrate;    /// status whether it is ready to migrate
235   CmiBool  enable_measure;
236   int  nextPe;              /// next migration dest processor
237 #else
238   void AsyncMigrate(CmiBool use){};
239 #endif
240 /**FAULT_EVAC*/
241 private:
242         CmiBool asyncEvacuate; //can the element be evacuated anytime, false for tcharm 
243         CmiBool bounced; //did this element try to immigrate into a processor which was evacuating
244                                                                                         // and was bounced away to some other processor. This is assumed to happen
245                                                                                         //only if this object was migrated by a load balancer, but the processor
246                                                                                         // started crashing soon after
247 public: 
248         CmiBool isAsyncEvacuate(){return asyncEvacuate;}
249         void AsyncEvacuate(CmiBool set){asyncEvacuate = set;}
250         CmiBool isBounced(){return bounced;}
251         void Bounced(CmiBool set){bounced = set;}
252 };
253 class CkLocRec_remote;
254
255 /*********************** CkMigratable ******************************/
256 /** This is the superclass of all migratable parallel objects.
257  *  Currently, that's just array elements.
258  */
259 #if CMK_OUT_OF_CORE
260 #  include "conv-ooc.h"
261 extern CooPrefetchManager CkArrayElementPrefetcher;
262 // If this flag is set, this creation/deletion is just 
263 //   a "fake" constructor/destructor call for prefetching.
264 CkpvExtern(int,CkSaveRestorePrefetch);
265 #endif
266
267 class CkMigratable : public Chare {
268 protected:
269   CkLocRec_local *myRec;
270 private:
271   int thisChareType;//My chare type
272   void commonInit(void);
273   CmiBool asyncEvacuate;
274 public:
275   CkArrayIndex thisIndexMax;
276
277   CkMigratable(void);
278   CkMigratable(CkMigrateMessage *m);
279   virtual ~CkMigratable();
280   virtual void pup(PUP::er &p);
281   virtual void CkAddThreadListeners(CthThread tid, void *msg);
282
283   virtual int ckGetChareType(void) const;// {return thisChareType;}
284   const CkArrayIndex &ckGetArrayIndex(void) const {return myRec->getIndex();}
285
286 #if CMK_LBDB_ON  //For load balancing:
287   //Suspend load balancer measurements (e.g., before CthSuspend)
288   inline void ckStopTiming(void) {myRec->stopTiming();}
289   //Begin load balancer measurements again (e.g., after CthSuspend)
290   inline void ckStartTiming(void) {myRec->startTiming();}
291   inline LBDatabase *getLBDB(void) const {return myRec->getLBDB();}
292 #else
293   inline void ckStopTiming(void) { }
294   inline void ckStartTiming(void) { }
295 #endif
296
297   /// for inline call
298   LDObjHandle timingBeforeCall(int *objstopped);
299   void timingAfterCall(LDObjHandle objHandle,int *objstopped);
300
301   //Initiate a migration to the given processor
302   inline void ckMigrate(int toPe) {myRec->migrateMe(toPe);}
303   
304   /// Called by the system just before and after migration to another processor:  
305   virtual void ckAboutToMigrate(void); /*default is empty*/
306   virtual void ckJustMigrated(void); /*default is empty*/
307
308   //used for out-of-core emulation
309   virtual void ckJustRestored(void); /*default is empty*/
310
311   /// Delete this object
312   virtual void ckDestroy(void);
313
314   /// Execute the given entry method.  Returns false if the element 
315   /// deleted itself or migrated away during execution.
316   inline CmiBool ckInvokeEntry(int epIdx,void *msg,CmiBool doFree) 
317           {return myRec->invokeEntry(this,msg,epIdx,doFree);}
318
319 protected:
320   /// A more verbose form of abort
321   virtual void CkAbort(const char *str) const;
322
323   CmiBool usesAtSync;//You must set this in the constructor to use AtSync().
324   CmiBool usesAutoMeasure; //You must set this to use auto lb instrumentation.
325   CmiBool barrierRegistered;//True iff barrier handle below is set
326
327 public:
328   virtual void ResumeFromSync(void);
329   virtual void UserSetLBLoad(void);  /// user define this when setLBLoad is true
330   void setObjTime(double cputime);
331   double getObjTime();
332
333 #if CMK_LBDB_ON  //For load balancing:
334   void AtSync(int waitForMigration=1);
335   int MigrateToPe()  { return myRec->MigrateToPe(); }
336
337 private: //Load balancer state:
338   LDBarrierClient ldBarrierHandle;//Transient (not migrated)  
339   LDBarrierReceiver ldBarrierRecvHandle;//Transient (not migrated)  
340   static void staticResumeFromSync(void* data);
341 public:
342   void ReadyMigrate(CmiBool ready);
343   void ckFinishConstruction(void);
344   void setMigratable(int migratable);
345 #else
346   void AtSync(int waitForMigration=1) { ResumeFromSync();}
347   void setMigratable(int migratable)  { }
348 public:
349   void ckFinishConstruction(void) { }
350 #endif
351
352 #if CMK_OUT_OF_CORE
353 private:
354   friend class CkLocMgr;
355   friend int CkArrayPrefetch_msg2ObjId(void *msg);
356   friend void CkArrayPrefetch_writeToSwap(FILE *swapfile,void *objptr);
357   friend void CkArrayPrefetch_readFromSwap(FILE *swapfile,void *objptr);
358   int prefetchObjID; //From CooRegisterObject
359   CmiBool isInCore; //If true, the object is present in memory
360 #endif
361
362   // FAULT_EVAC
363   void AsyncEvacuate(CmiBool set){myRec->AsyncEvacuate(set);asyncEvacuate = set;};
364 public:
365   CmiBool isAsyncEvacuate(){return asyncEvacuate;};
366 };
367
368 /** 
369  * Stores a list of array elements.  These lists are 
370  * kept by the array managers. 
371  */
372 class CkMigratableList {
373         CkVec< CkZeroPtr<CkMigratable> > el;
374  public:
375         CkMigratableList();
376         ~CkMigratableList();
377         
378         void setSize(int s);
379         inline int length(void) const {return el.length();}
380
381         /// Add an element at the given location
382         void put(CkMigratable *v,int atIdx);
383
384         /// Return the element at the given location
385         inline CkMigratable *get(int localIdx) {return el[localIdx];}
386
387         /**
388          * Return the next non-empty element starting from the given index,
389          * or NULL if there is none.  Updates from to point past the returned index.
390         */
391         CkMigratable *next(int &from) {
392                 while (from<length()) {
393                         CkMigratable *ret=el[from];
394                         from++;
395                         if (ret!=NULL) return ret;
396                 }
397                 return NULL;
398         }
399
400         /// Remove the element at the given location
401         inline void empty(int localIdx) {el[localIdx]=NULL;}
402 };
403
404 /**
405  *A typed version of the above.
406  */
407 template <class T>
408 class CkMigratableListT : public CkMigratableList {
409         typedef CkMigratableList super;
410 public:
411         inline void put(T *v,int atIdx) {super::put((CkMigratable *)v,atIdx);}
412         inline T *get(int localIdx) {return (T *)super::get(localIdx);}
413         inline T *next(int &from) {return (T *)super::next(from);}
414 };
415
416
417 /********************** CkLocMgr ********************/
418 /// A tiny class for detecting heap corruption
419 class CkMagicNumber_impl {
420  protected:
421         int magic;
422         void badMagicNumber(int expected,const char *file,int line,void *obj) const;
423         CkMagicNumber_impl(int m);
424 };
425 template<class T>
426 class CkMagicNumber : public CkMagicNumber_impl {
427         enum {good=sizeof(T)^0x7EDC0000};
428  public:
429         CkMagicNumber(void) :CkMagicNumber_impl(good) {}
430         inline void check(const char *file,int line,void *obj) const {
431                 if (magic!=good) badMagicNumber(good,file,line,obj);
432         }
433 #if CMK_ERROR_CHECKING
434 #   define CK_MAGICNUMBER_CHECK magic.check(__FILE__,__LINE__,this);
435 #else
436 #   define CK_MAGICNUMBER_CHECK /*empty, for speed*/
437 #endif
438 };
439
440 /**
441  * The "data" class passed to a CkLocIterator, which refers to a bound
442  * glob of array elements.
443  * This is a transient class-- do not attempt to store it or send 
444  * it across processors.
445  */
446
447         
448 class CkLocation {
449         CkLocMgr *mgr;
450         CkLocRec_local *rec;
451 public:
452         CkLocation(CkLocMgr *mgr_, CkLocRec_local *rec_);
453         
454         /// Find our location manager
455         inline CkLocMgr *getManager(void) const {return mgr;}
456         
457         /// Find the local record that refers to this element
458         inline CkLocRec_local *getLocalRecord(void) const {return rec;}
459         
460         /// Look up and return the array index of this location.
461         const CkArrayIndex &getIndex(void) const;
462         
463         void destroyAll();
464
465         /// Pup all the array elements at this location.
466         void pup(PUP::er &p);
467 };
468
469 /**
470  * This interface describes the destination for an iterator over
471  * the locations in an array.
472  */
473 class CkLocIterator {
474 public:
475         virtual ~CkLocIterator();
476         
477         /// This location is part of the calling location manager.
478         virtual void addLocation(CkLocation &loc) =0;
479 };
480
481 enum CkElementCreation_t {
482   CkElementCreation_migrate=2, // Create object for normal migration arrival
483   CkElementCreation_resume=3,  // Create object after checkpoint
484   CkElementCreation_restore=4  // Create object after checkpoint, skip listeners
485 };
486 /// Abstract superclass of all array manager objects 
487 class CkArrMgr {
488 public:
489         virtual ~CkArrMgr() {}
490         /// Insert this initial element on this processor
491         virtual void insertInitial(const CkArrayIndex &idx,void *ctorMsg, int local=1)=0;
492         
493         /// Done with initial insertions
494         virtual void doneInserting(void)=0;
495         
496         /// Create an uninitialized element after migration
497         ///  The element's constructor will be called immediately after.
498         virtual CkMigratable *allocateMigrated(int elChareType,
499                 const CkArrayIndex &idx,CkElementCreation_t type) =0;
500
501         /// Demand-create an element at this index on this processor
502         ///  Returns true if the element was successfully added;
503         ///  false if the element migrated away or deleted itself.
504         virtual CmiBool demandCreateElement(const CkArrayIndex &idx,
505                 int onPe,int ctor,CkDeliver_t type) =0;
506 };
507
508
509 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
510 typedef void (*CkLocFn)(CkArray *,void *,CkLocRec *,CkArrayIndex *);
511 #endif
512
513
514 /**
515  * A group which manages the location of an indexed set of
516  * migratable objects.  Knows about insertions, deletions,
517  * home processors, migration, and message forwarding.
518  */
519 class CkLocMgr : public IrrGroup {
520         CkMagicNumber<CkMigratable> magic; //To detect heap corruption
521 public:
522         CkLocMgr(CkGroupID map,CkGroupID _lbdb,CkArrayIndex& numInitial);
523         CkLocMgr(CkMigrateMessage *m);
524         inline CmiBool isLocMgr(void) { return CmiTrue; }
525         CkGroupID &getGroupID(void) {return thisgroup;}
526         inline CProxy_CkLocMgr &getProxy(void)
527                 {return thisProxy;}
528         inline CProxyElement_CkLocMgr &getLocalProxy(void)
529                 {return thislocalproxy;}
530
531 //Interface used by array manager and proxies
532         /// Add a new local array manager to our list.  Array managers
533         ///  must be registered in the same order on all processors.
534         /// Returns a list which will contain that array's local elements
535         CkMigratableList *addManager(CkArrayID aid,CkArrMgr *mgr);
536
537         /// Populate this array with initial elements
538         void populateInitial(CkArrayIndex& numElements,void *initMsg,CkArrMgr *mgr)
539                 {map->populateInitial(mapHandle,numElements,initMsg,mgr);}
540
541         /// Add a new local array element, calling element's constructor
542         ///  Returns true if the element was successfully added;
543         ///  false if the element migrated away or deleted itself.
544         CmiBool addElement(CkArrayID aid,const CkArrayIndex &idx,
545                 CkMigratable *elt,int ctorIdx,void *ctorMsg);
546
547         ///Deliver message to this element:
548         inline void deliverViaQueue(CkMessage *m) {deliver(m,CkDeliver_queue);}
549         inline void deliverInline(CkMessage *m) {deliver(m,CkDeliver_inline);}
550         int deliver(CkMessage *m, CkDeliver_t type, int opts=0);
551
552         ///Done inserting elements for now
553         void doneInserting(void);
554         void startInserting(void);
555
556         // How many elements of each associated array are local to this PE?
557         // If this returns n, and there are k associated arrays, that
558         // means k*n elements are living here
559         unsigned int numLocalElements();
560
561 //Advisories:
562         ///This index now lives on the given processor-- update local records
563         void inform(const CkArrayIndex &idx,int nowOnPe);
564
565         ///This index now lives on the given processor-- tell the home processor
566         void informHome(const CkArrayIndex &idx,int nowOnPe);
567
568         ///This message took several hops to reach us-- fix it
569         void multiHop(CkArrayMessage *m);
570
571 //Interface used by CkLocRec_local
572         //Look up the object with this local index
573         inline CkMigratable *lookupLocal(int localIdx,CkArrayID arrayID) {
574 #if CMK_ERROR_CHECKING
575                 if (managers.find(arrayID)->mgr==NULL)
576                         CkAbort("CkLocMgr::lookupLocal called for unknown array!\n");
577 #endif
578                 if (managers.find(arrayID)->mgr==NULL)
579                         CkAbort("CkLocMgr::lookupLocal called for unknown array!\n");
580                 return managers.find(arrayID)->elts.get(localIdx);
581         }
582
583         //Migrate us to another processor
584         void emigrate(CkLocRec_local *rec,int toPe);
585
586 #if CMK_LBDB_ON
587         LBDatabase *getLBDB(void) const { return the_lbdb; }
588         const LDOMHandle &getOMHandle(void) const { return myLBHandle; }
589 #endif
590
591         //This index will no longer be used-- delete the associated elements
592         void reclaim(const CkArrayIndex &idx,int localIdx);
593
594         int getSpringCount(void) const { return nSprings; }
595
596         CmiBool demandCreateElement(CkArrayMessage *msg,int onPe,CkDeliver_t type);
597
598 //Interface used by external users:
599         /// Home mapping
600         inline int homePe(const CkArrayIndex &idx) const
601                 {return map->homePe(mapHandle,idx);}
602         inline int procNum(const CkArrayIndex &idx) const
603                 {return map->procNum(mapHandle,idx);}
604         inline CmiBool isHome(const CkArrayIndex &idx) const
605                 {return (CmiBool)(homePe(idx)==CkMyPe());}
606
607         /// Look up the object with this array index, or return NULL
608         CkMigratable *lookup(const CkArrayIndex &idx,CkArrayID aid);
609
610         /// Return the "last-known" location (returns a processor number)
611         int lastKnown(const CkArrayIndex &idx);
612
613         /// Return true if this array element lives on another processor
614         bool isRemote(const CkArrayIndex &idx,int *onPe) const;
615
616 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
617         //mark the duringMigration variable .. used for parallel restart
618         void setDuringMigration(CmiBool _duringMigration);
619 #endif
620
621         /// Pass each of our locations (each separate array index) to this destination.
622         void iterate(CkLocIterator &dest);
623
624         /// Insert and unpack this array element from this checkpoint (e.g., from CkLocation::pup), skip listeners
625         void restore(const CkArrayIndex &idx, PUP::er &p);
626         /// Insert and unpack this array element from this checkpoint (e.g., from CkLocation::pup)
627 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
628         void resume(const CkArrayIndex &idx, PUP::er &p, CmiBool create, int dummy=0);
629 #else
630         void resume(const CkArrayIndex &idx, PUP::er &p, CmiBool notify=CmiTrue);
631 #endif
632
633 //Communication:
634         void immigrate(CkArrayElementMigrateMessage *msg);
635         void updateLocation(const CkArrayIndex &idx,int nowOnPe);
636         void reclaimRemote(const CkArrayIndex &idx,int deletedOnPe);
637         void dummyAtSync(void);
638
639         /// return a list of migratables in this local record
640         void migratableList(CkLocRec_local *rec, CkVec<CkMigratable *> &list);
641
642         void flushAllRecs(void);
643         void checkpointRemoteIdx(PUP::er &p);
644         void pup(PUP::er &p);
645         
646         //Look up array element in hash table.  Index out-of-bounds if not found.
647         CkLocRec *elementRec(const CkArrayIndex &idx);
648         //Look up array element in hash table.  Return NULL if not there.
649         CkLocRec *elementNrec(const CkArrayIndex &idx);
650
651
652 private:
653 //Internal interface:
654         //Add given element array record at idx, replacing the existing record
655         void insertRec(CkLocRec *rec,const CkArrayIndex &idx);
656         //Add given record, when there is guarenteed to be no prior record
657         void insertRecN(CkLocRec *rec,const CkArrayIndex &idx);
658         //Insert a remote record at the given index
659         CkLocRec_remote *insertRemote(const CkArrayIndex &idx,int nowOnPe);
660
661         //Remove this entry from the table (does not delete record)
662         void removeFromTable(const CkArrayIndex &idx);
663
664         friend class CkLocation; //so it can call pupElementsFor
665         friend class ArrayElement;
666         friend class MemElementPacker;
667 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
668         void pupElementsFor(PUP::er &p,CkLocRec_local *rec,
669         CkElementCreation_t type, CmiBool create=CmiTrue, int dummy=0);
670 #else
671         void pupElementsFor(PUP::er &p,CkLocRec_local *rec,
672                 CkElementCreation_t type);
673 #endif
674
675         /// Call this member function on each element of this location:
676         typedef void (CkMigratable::* CkMigratable_voidfn_t)(void);
677
678         CmiBool deliverUnknown(CkArrayMessage *msg,CkDeliver_t type,int opts);
679
680         /// Create a new local record at this array index.
681 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
682 CkLocRec_local *createLocal(const CkArrayIndex &idx,
683         CmiBool forMigration, CmiBool ignoreArrival,
684         CmiBool notifyHome,int dummy=0);
685 #else
686         CkLocRec_local *createLocal(const CkArrayIndex &idx, 
687                 CmiBool forMigration, CmiBool ignoreArrival,
688                 CmiBool notifyHome);
689 #endif
690
691 public:
692         void callMethod(CkLocRec_local *rec,CkMigratable_voidfn_t fn);
693
694 //Data Members:
695         //Map array ID to manager and elements
696         class ManagerRec {
697         public:
698                 ManagerRec *next; //next non-null array manager
699                 CkArrMgr *mgr;
700                 CkMigratableList elts;
701                 ManagerRec() {
702                         next=NULL;
703                         mgr=NULL;
704                 }
705                 void init(void) { next=NULL; mgr=NULL; }
706                 CkMigratable *element(int localIdx) {
707                         return elts.get(localIdx);
708                 }
709         };
710         GroupIdxArray<ManagerRec *> managers;
711         int nManagers;
712         ManagerRec *firstManager; //First non-null array manager
713
714         CmiBool addElementToRec(CkLocRec_local *rec,ManagerRec *m,
715                 CkMigratable *elt,int ctorIdx,void *ctorMsg);
716
717         //For keeping track of free local indices
718         CkVec<int> freeList;//Linked list of free local indices
719         int firstFree;//First free local index
720         int localLen;//Last allocated local index plus one
721         int nextFree(void);
722
723         CProxy_CkLocMgr thisProxy;
724         CProxyElement_CkLocMgr thislocalproxy;
725         /// The core of the location manager: map array index to element representative
726         CkHashtableT<CkArrayIndex,CkLocRec *> hash;
727         CmiImmediateLockType hashImmLock;
728
729         /// This flag is set while we delete an old copy of a migrator
730         CmiBool duringMigration;
731
732         //Occasionally clear out stale remote pointers
733         static void staticSpringCleaning(void *mgr,double curWallTime);
734         void springCleaning(void);
735         int nSprings;
736
737         //Map object
738         CkGroupID mapID;
739         int mapHandle;
740         CkArrayMap *map;
741
742         CkGroupID lbdbID;
743 #if CMK_LBDB_ON
744         LBDatabase *the_lbdb;
745         LDBarrierClient dummyBarrierHandle;
746         static void staticDummyResumeFromSync(void* data);
747         void dummyResumeFromSync(void);
748         static void staticRecvAtSync(void* data);
749         void recvAtSync(void);
750         LDOMHandle myLBHandle;
751 #endif
752         void initLB(CkGroupID lbdbID);
753
754 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
755 public:
756         void callForAllRecords(CkLocFn,CkArray *,void *);
757         int homeElementCount;
758 #endif
759
760 };
761
762
763
764
765
766 /// check the command line arguments to determine if we can use ConfigurableRRMap
767 bool haveConfigurableRRMap();
768
769
770
771
772 /*@}*/
773
774 #endif /*def(thisHeader)*/