Delegated readonly proxies did not work previously, as pupping them during
authorLukasz Wesolowski <wesolwsk@talent.cs.illinois.edu>
Wed, 25 May 2011 22:02:46 +0000 (17:02 -0500)
committerLukasz Wesolowski <wesolwsk@talent.cs.illinois.edu>
Fri, 9 Sep 2011 18:13:08 +0000 (13:13 -0500)
startup on processors other than 0 would cause an attempted access to
the delegated group manager which was not yet created. This commit implements
a work-around in which a temporary object (delegated manager) is created to
use in the pup method.

src/ck-core/charm++.h
src/ck-core/ck.C
src/ck-core/init.h

index a1ba7c7d90acbe9a88cbd14c3ae146b18b9d3c03..e506f2b5c5b49db1b52153a3cb59b3fd12c8186c 100644 (file)
@@ -562,10 +562,13 @@ class CkDelegateMgr;
 */
 class CProxy {
   private:
-    CkDelegateMgr *delegatedMgr; // can be either a group or a nodegroup
+    CkGroupID delegatedGroupId;      
+    int isNodeGroup; 
+    mutable CkDelegateMgr *delegatedMgr; // can be either a group or a nodegroup
     CkDelegateData *delegatedPtr; // private data for use by delegatedMgr.
   protected: //Never allocate CProxy's-- only subclass them.
-    CProxy() :delegatedMgr(0), delegatedPtr(0) { }
+ CProxy() :delegatedMgr(0), delegatedPtr(0), isNodeGroup(0) 
+      {delegatedGroupId.setZero(); }
 
 #define CK_DELCTOR_PARAM CkDelegateMgr *dTo,CkDelegateData *dPtr
 #define CK_DELCTOR_ARGS dTo,dPtr
@@ -576,8 +579,11 @@ class CProxy {
        :delegatedMgr(dTo)
         {
             delegatedPtr = NULL;
-            if(delegatedMgr != NULL && dPtr != NULL) 
-                delegatedPtr = dTo->ckCopyDelegateData(dPtr);            
+            if(delegatedMgr != NULL && dPtr != NULL) {
+                delegatedPtr = delegatedMgr->ckCopyDelegateData(dPtr);            
+               delegatedGroupId = delegatedMgr->CkGetGroupID();
+               isNodeGroup = delegatedMgr->isNodeGroup();
+           }
         }
   public:
     /// Copy constructor.  Only needed for delegated proxies.
@@ -610,7 +616,23 @@ class CProxy {
     
     /// Return the delegator of this proxy, to which the proxies' messages
     ///  are actually sent.
-    inline CkDelegateMgr *ckDelegatedTo(void) const { return delegatedMgr; }
+    inline CkDelegateMgr *ckDelegatedTo(void) const { 
+
+      // needed if proxy was defined before group creation 
+      // (i.e. for delegated readonly proxies)
+      if (delegatedMgr == NULL && !delegatedGroupId.isZero()) {
+       if (isNodeGroup) {
+         delegatedMgr=(CkDelegateMgr *)CkLocalNodeBranch(delegatedGroupId);
+       }
+       else {
+         delegatedMgr=(CkDelegateMgr *)CkLocalBranch(delegatedGroupId);
+       }
+      }
+
+      return delegatedMgr; 
+    }
+
+    
     
     /// Return the delegator's local data associated with this proxy.
     inline CkDelegateData *ckDelegatedPtr(void) const {return delegatedPtr;}
index deacaf4040bdf96b8a218aa892f8f20143ea4cd1..16f451144772353a3d771aa8599342ad1d690894 100644 (file)
@@ -292,20 +292,24 @@ void CProxy::ckDelegate(CkDelegateMgr *dTo,CkDelegateData *dPtr) {
        ckUndelegate();
        delegatedMgr = dTo;
        delegatedPtr = dPtr;
+        delegatedGroupId = delegatedMgr->CkGetGroupID();
+        isNodeGroup = delegatedMgr->isNodeGroup();
 }
 void CProxy::ckUndelegate(void) {
        delegatedMgr=NULL;
+        delegatedGroupId.setZero();
        if (delegatedPtr) delegatedPtr->unref();
        delegatedPtr=NULL;
 }
 
 /// Copy constructor
 CProxy::CProxy(const CProxy &src)
-    :delegatedMgr(src.delegatedMgr)
-{
+  :delegatedMgr(src.delegatedMgr), delegatedGroupId(src.delegatedGroupId), 
+   isNodeGroup(src.isNodeGroup) {
     delegatedPtr = NULL;
-    if(delegatedMgr != NULL && src.delegatedPtr != NULL)
+    if(delegatedMgr != NULL && src.delegatedPtr != NULL) {
         delegatedPtr = src.delegatedMgr->ckCopyDelegateData(src.delegatedPtr);
+    }
 }
 
 /// Assignment operator
@@ -313,6 +317,8 @@ CProxy& CProxy::operator=(const CProxy &src) {
        CkDelegateData *oldPtr=delegatedPtr;
        ckUndelegate();
        delegatedMgr=src.delegatedMgr;
+        delegatedGroupId = src.delegatedGroupId; 
+        isNodeGroup = src.isNodeGroup;
 
         if(delegatedMgr != NULL && src.delegatedPtr != NULL)
             delegatedPtr = delegatedMgr->ckCopyDelegateData(src.delegatedPtr);
@@ -325,29 +331,58 @@ CProxy& CProxy::operator=(const CProxy &src) {
 }
 
 void CProxy::pup(PUP::er &p) {
-      CkGroupID delegatedTo;
-      delegatedTo.setZero();
-      int isNodeGroup = 0;
-      if (!p.isUnpacking()) {
-        if (delegatedMgr) {
-          delegatedTo = delegatedMgr->CkGetGroupID();
-         isNodeGroup = delegatedMgr->isNodeGroup();
-        }
-      }
-      p|delegatedTo;
-      if (!delegatedTo.isZero()) {
-        p|isNodeGroup;
-        if (p.isUnpacking()) {
-         if (isNodeGroup)
-               delegatedMgr=(CkDelegateMgr *)CkLocalNodeBranch(delegatedTo);
-         else
-               delegatedMgr=(CkDelegateMgr *)CkLocalBranch(delegatedTo);
-       }
+  if (!p.isUnpacking()) {
+    if (ckDelegatedTo() != NULL) {
+      delegatedGroupId = delegatedMgr->CkGetGroupID();
+      isNodeGroup = delegatedMgr->isNodeGroup();
+    }
+  }
+  p|delegatedGroupId;
+  if (!delegatedGroupId.isZero()) {
+    p|isNodeGroup;
+    if (p.isUnpacking()) {
+      delegatedMgr = ckDelegatedTo(); 
+    }
+
+    // if delegated manager has not been created, construct a dummy
+    // object on which to call DelegatePointerPup
+    if (delegatedMgr == NULL) {
 
-        delegatedPtr = delegatedMgr->DelegatePointerPup(p,delegatedPtr);
-       if (p.isUnpacking() && delegatedPtr)
-            delegatedPtr->ref();
+      int migCtor; 
+      if (isNodeGroup) {
+        CmiImmediateLock(CksvAccess(_nodeGroupTableImmLock));
+        migCtor = 
+          CksvAccess(_nodeGroupTable)->find(delegatedGroupId).getmigCtor();
+        CmiImmediateUnlock(CksvAccess(_nodeGroupTableImmLock));
       }
+      else  {
+        CmiImmediateLock(CkpvAccess(_groupTableImmLock));
+        migCtor = 
+          CkpvAccess(_groupTable)->find(delegatedGroupId).getmigCtor();
+        CmiImmediateUnlock(CkpvAccess(_groupTableImmLock));
+      } 
+
+      // create a dummy object for calling DelegatePointerPup
+      int objId = _entryTable[migCtor]->chareIdx; 
+      int objSize = _chareTable[objId]->size; 
+      void *obj = malloc(objSize); 
+      _entryTable[migCtor]->call(NULL, obj); 
+      delegatedPtr = static_cast<CkDelegateMgr *> (obj)
+        ->DelegatePointerPup(p, delegatedPtr);           
+      free(obj);
+
+    }
+    else {
+
+      // delegated manager has been created, so we can use it
+      delegatedPtr = delegatedMgr->DelegatePointerPup(p,delegatedPtr);
+
+    }
+
+    if (p.isUnpacking() && delegatedPtr) {
+      delegatedPtr->ref();
+    }
+  }
 }
 
 /**** Array sections */
@@ -532,7 +567,7 @@ extern "C" void CkDeliverMessageFree(int epIdx,void *msg,void *obj)
   //fflush(stdout);
 #if CMK_CHARMDEBUG
   CpdBeforeEp(epIdx, obj, msg);
-#endif
+#endif    
   _entryTable[epIdx]->call(msg, obj);
 #if CMK_CHARMDEBUG
   CpdAfterEp(epIdx);
index 97dcc68b6d83bc6effabacb35cd1ca6d8c00e0bd..c914d1289de56872a8380a1ccbfce665e60a97cd 100644 (file)
@@ -32,6 +32,7 @@ class TableEntry {
       cIdx = cIdx_;
     }
     inline int getcIdx(void) const { return cIdx; }
+    inline int getmigCtor(void) const { return migCtor; }
 };
 
 template <class dtype>