Added a user-specified-ID method for getting and setting globals.
authorOrion Lawlor <olawlor@acm.org>
Fri, 23 Aug 2002 21:14:40 +0000 (21:14 +0000)
committerOrion Lawlor <olawlor@acm.org>
Fri, 23 Aug 2002 21:14:40 +0000 (21:14 +0000)
src/libs/ck-libs/tcharm/tcharm.C
src/libs/ck-libs/tcharm/tcharm_impl.h
src/libs/ck-libs/tcharm/tcharmc.h

index 587844fa2922d195a61239c5279be412a54f72c4..308e5bcd6ea4292342db0aa88d50f39b08812494 100644 (file)
@@ -172,6 +172,7 @@ void TCharm::pup(PUP::er &p) {
   p(nUd);
   for(int i=0;i<nUd;i++) 
     ud[i].pup(p);
+  sud.pup(p);
   TCharm::setState(inFramework);
 
   if (!p.isUnpacking()) 
@@ -196,15 +197,16 @@ void TCharm::UserData::pup(PUP::er &p)
   if (isC) { //C version
     //FIXME: function pointers may not be valid across processors
     p((void*)&cfn, sizeof(TCpupUserDataC));
-    cfn(pext,data);
+    if (cfn) cfn(pext,data);
   } 
   else { //Fortran version
     //FIXME: function pointers may not be valid across processors
     p((void*)&ffn, sizeof(TCpupUserDataF));        
-    ffn(pext,data);
+    if (ffn) ffn(pext,data);
   }
 }
 
+
 TCharm::~TCharm() 
 {
   CmiIsomallocBlockListDelete(heapBlocks);
@@ -685,6 +687,27 @@ CDECL void *TCharmGetUserdata(int id)
 FDECL void *FTN_NAME(TCHARM_GET_USERDATA,tcharm_get_userdata)(int *id)
 { return TCharmGetUserdata(*id); }
 
+CDECL void TCharmSetGlobal(int globalID,void *new_value,TCharmPupGlobalFn pup_or_NULL)
+{
+       TCHARMAPI("TCharmSetGlobal");
+       TCharm *tc=TCharm::get();
+       if (tc->sud.length()<=globalID) 
+       { //We don't have room for this ID yet: make room
+               int newLen=2*globalID;
+               tc->sud.setSize(newLen);
+               tc->sud.length()=newLen;
+       }
+       tc->sud[globalID]=TCharm::UserData((TCharmPupFn) pup_or_NULL,new_value);
+}
+CDECL void *TCharmGetGlobal(int globalID)
+{
+       //Skip TCHARMAPI("TCharmGetGlobal") because there's no dynamic allocation here,
+       // and this routine should be as fast as possible.
+       CkVec<TCharm::UserData> &v=TCharm::get()->sud;
+       if (v.length()<=globalID) return NULL; //Uninitialized global
+       return v[globalID].getData();
+}
+
 CDECL void TCharmMigrate(void)
 {
        TCHARMAPI("TCharmMigrate");
index 029c7ac1b260e389200cf2772b2781b85d292131..0b893aea01dee2ce8e217c9a99ded191bd72df53 100644 (file)
@@ -79,15 +79,18 @@ class TCharm: public ArrayElement1D
                TCpupUserDataC cfn;
                TCpupUserDataF ffn;
        public:
-               UserData() {data=NULL; cfn=NULL; ffn=NULL;}
+               UserData(int i=0) {data=NULL; cfn=NULL; ffn=NULL;}
                UserData(TCpupUserDataC cfn_,void *data_)
                        {cfn=cfn_; data=data_; isC=true;}
                class isFortran{};
                UserData(TCpupUserDataF ffn_,void *data_,isFortran tag)
                        {ffn=ffn_; data=data_; isC=false;}
-               void *getData(void) {return data;}
+               inline void *getData(void) const {return data;}
                void pup(PUP::er &p);
+               friend inline void operator|(PUP::er &p,UserData &d) {d.pup(p);}
        };
+       //New interface for user data:
+       CkPupVec<UserData> sud;
        
        //One-time initialization
        static void nodeInit(void);
@@ -109,6 +112,7 @@ class TCharm: public ArrayElement1D
        ThreadInfo threadInfo;
        double timeOffset; //Value to add to CkWallTimer to get my clock
 
+       //Old interface for user data:
        enum {maxUserData=16};
        int nUd;
        UserData ud[maxUserData];
index 94c3251964a0b57b0ab386595903be90b69b3c2c..ce21fbe88c54748dd3c85d333050a9135b521efb 100644 (file)
@@ -46,12 +46,19 @@ int TCharmGetNumChunks(void);
 int TCharmElement(void);
 int TCharmNumElements(void);
 void TCharmBarrier(void);
+void TCharmMigrate(void);
+void TCharmDone(void);
 
+/* Set/get thread-private ("thread global") data. */
 typedef void (*TCharmPupFn)(pup_er p,void *data);
 int TCharmRegister(void *data,TCharmPupFn pfn);
 void *TCharmGetUserdata(int id);
-void TCharmMigrate(void);
-void TCharmDone(void);
+
+/* Alternate API for Set/get thread-private ("thread global") data. */
+typedef void (*TCharmPupGlobalFn)(pup_er p);
+void TCharmSetGlobal(int globalID,void *new_value,TCharmPupGlobalFn pup_or_NULL);
+void *TCharmGetGlobal(int globalID);
+
 
 /*Get the local wall clock.  Unlike CkWalltimer, is
   monotonically increasing, even with migration and