Added ability to register a set of global variables, which are
authorOrion Lawlor <olawlor@acm.org>
Fri, 7 Dec 2001 23:53:46 +0000 (23:53 +0000)
committerOrion Lawlor <olawlor@acm.org>
Fri, 7 Dec 2001 23:53:46 +0000 (23:53 +0000)
pup'd into a buffer on processor 0 after init, and pup'd out
on every other node.  The implementation needs work-- there is
much data duplication and potential for race conditions.

src/libs/ck-libs/tcharm/tcharm.C
src/libs/ck-libs/tcharm/tcharm.ci
src/libs/ck-libs/tcharm/tcharm.h
src/libs/ck-libs/tcharm/tcharmc.h
src/libs/ck-libs/tcharm/tcharmf.h

index f7bcbadec6ad1b8647fa7aa08e2e024cb6035a73..e2c14d69892d4948bcb11f757a9784455c4e3e95 100644 (file)
@@ -22,8 +22,10 @@ void TCharm::nodeInit(void)
 {
   CtvInitialize(TCharm *,_curTCharm);
   CpvInitialize(inState,_stateTCharm);
+  TCharm::setState(inNodeSetup);
   TCharmUserNodeSetup();
   FTN_NAME(TCHARM_USER_NODE_SETUP,tcharm_user_node_setup)();
+  TCharm::setState(inInit);
 }
 
 static void startTCharmThread(TCharmInitMsg *msg)
@@ -37,8 +39,7 @@ static void startTCharmThread(TCharmInitMsg *msg)
 TCharm::TCharm(TCharmInitMsg *initMsg_)
 {
   initMsg=initMsg_;
-  
-tid=CthCreateMigratable((CthVoidFn)startTCharmThread,initMsg,initMsg->stackSize);
+  tid=CthCreateMigratable((CthVoidFn)startTCharmThread,initMsg,initMsg->stackSize);
   CtvAccessOther(tid,_curTCharm)=this;
   TCharm::setState(inInit);
   isStopped=true;
@@ -219,6 +220,41 @@ static void TCharmBuildThreads(TCharmInitMsg *msg,TCharmSetupCookie &cook)
        cook.setThreads(id,msg->numElements);
 }
 
+/****** Readonlys *****/
+CkVec<TCpupReadonlyGlobal> TCharmReadonlys::entries;
+void TCharmReadonlys::add(TCpupReadonlyGlobal fn)
+{
+       entries.push_back(fn);
+}
+//Pups all registered readonlys
+void TCharmReadonlys::pup(PUP::er &p) {
+       if (p.isUnpacking()) {
+               //HACK: Rather than sending this message only where its needed,
+               // we send it everywhere and just ignore it if it's not needed.
+               if (CkMyPe()==0) return; //Processor 0 is the source-- no unpacking needed
+               if (CkMyRank()!=0) return; //Some other processor will do the unpacking
+       }
+       //Pup the globals for this node:
+       int i,n=entries.length();
+       p(n);
+       if (n!=entries.length())
+               CkAbort("TCharmReadonly list length mismatch!\n");
+       for (i=0;i<n;i++)
+               (entries[i])((pup_er)&p);
+}
+
+CDECL void TCharmReadonlyGlobals(TCpupReadonlyGlobal fn)
+{
+       if (TCharm::getState()!=inNodeSetup)
+               CkAbort("Can only call TCharmReadonlyGlobals from in TCharmUserNodeSetup!\n");
+       TCharmReadonlys::add(fn);
+}
+FDECL void FTN_NAME(TCHARM_READONLY_GLOBALS,tcharm_readonly_globals)
+       (TCpupReadonlyGlobal fn)
+{
+       TCharmReadonlyGlobals(fn);
+}
+
 /************* Startup/Shutdown Coordination Support ************/
 
 enum {TC_READY=23, TC_DONE=42};
@@ -341,6 +377,10 @@ public:
     
     if (0==TCharmCoordinator::getTotal())
            CkAbort("You didn't create any TCharm arrays in TCharmUserSetup!\n");
+
+    //Send out the readonly globals:
+    TCharmReadonlys r;
+    CProxy_TCharmReadonlyGroup::ckNew(r);
   }
 };
 
@@ -466,11 +506,15 @@ FDECL int FTN_NAME(TCHARM_NUM_ELEMENTS,tcharm_num_elements)(void)
 
 CDECL int TCharmRegister(void *data,TCharmPupFn pfn)
 { 
+       if (!CmiIsomallocInRange(data))
+               CkAbort("The UserData you register must be allocated on the stack!\n");
        return TCharm::get()->add(TCharm::UserData(pfn,data));
 }
 FDECL int FTN_NAME(TCHARM_REGISTER,tcharm_register)
        (void *data,TCpupUserDataF pfn)
 { 
+       if (!CmiIsomallocInRange(data))
+               CkAbort("The UserData you register must be allocated on the stack!\n");
        return TCharm::get()->add(TCharm::UserData(
                pfn,data,TCharm::UserData::isFortran()));
 }
index dc7589efa41970d838eb0c8ce7df6752c64bc0a7..ff491091de100e8c1345e0d65332ea77788fa66e 100644 (file)
@@ -10,4 +10,7 @@ module tcharm {
   mainchare TCharmMain {
     entry TCharmMain();
   };
+  group TCharmReadonlyGroup {
+    entry void TCharmReadonlyGroup(TCharmReadonlys r);
+  };
 };
index 4ceca058d3e1664308df9678c07949ceb7799de1..973db0c2d28bd08bcbb29d058adbf7ff4b609ae8 100644 (file)
@@ -10,9 +10,30 @@ Orion Sky Lawlor, olawlor@acm.org, 11/19/2001
 #ifndef __CHARM_TCHARM_H
 #define __CHARM_TCHARM_H
 
-#include "tcharm.decl.h"
+#include "pup.h"
 #include "pup_c.h"
 #include "charm-api.h"
+#include "tcharmc.h"
+#include "cklists.h"
+
+//User's readonly global variables, set exactly once after initialization
+class TCharmReadonlys {
+       //There's only one (shared) list per node, so no CpvAccess here
+       static CkVec<TCpupReadonlyGlobal> entries;
+ public:
+       static void add(TCpupReadonlyGlobal fn);
+       //Pups all registered readonlys
+       void pup(PUP::er &p);
+};
+PUPmarshall(TCharmReadonlys);
+
+#include "tcharm.decl.h"
+
+class TCharmReadonlyGroup : public Group {
+ public:
+       //Just unpacking the parameter is enough:
+       TCharmReadonlyGroup(const TCharmReadonlys &r) { /*nothing needed*/ }
+};
 
 class TCharm;
 
@@ -32,7 +53,7 @@ class TCharmInitMsg : public CMessage_TCharmInitMsg {
 };
 
 //Current computation location
-typedef enum {inInit,inDriver,inFramework,inPup} inState;
+typedef enum {inNodeSetup,inInit,inDriver,inFramework,inPup} inState;
 
 //Thread-local variables:
 CtvExtern(TCharm *,_curTCharm);
@@ -203,8 +224,6 @@ class TCharmSetupCookie {
        static TCharmSetupCookie *get(void) {return theCookie;}
 };
 
-#include "tcharmc.h"
-
 //Node setup callbacks: called at startup on each node
 FDECL void FTN_NAME(TCHARM_USER_NODE_SETUP,tcharm_user_node_setup)(void);
 FDECL void FTN_NAME(TCHARM_USER_SETUP,tcharm_user_setup)(void);
index 6cdb16711d8ea552fc17024ad7863db6fea2f81f..b2e0771178af13201061673b52c44939de57931f 100644 (file)
@@ -17,7 +17,14 @@ void TCharmUserNodeSetup(void);
 void TCharmUserSetup(void);
 
 
-/*Routines you can call from UserSetup:*/
+/**** Routines you can call from UserNodeSetup: ****/
+
+/*Register readonly global variables-- these will be broadcast
+after init and available in driver.*/
+typedef void (*TCpupReadonlyGlobal)(pup_er p);
+void TCharmReadonlyGlobals(TCpupReadonlyGlobal fn);
+
+/**** Routines you can call from UserSetup: ****/
 
 /*Set the size of the thread stack*/
 void TCharmSetStackSize(int newStackSize);
@@ -38,11 +45,8 @@ int TCharmArgc(void);
 /*Get the number of chunks we expect based on the command line*/
 int TCharmGetNumChunks(void);
 
-/*Implementation routines*/
-void TCharmInDefaultSetup(void);
 
-
-/*Routines you can call from a thread*/
+/**** Routines you can call from the thread (driver) ****/
 int TCharmElement(void);
 int TCharmNumElements(void);
 
@@ -52,6 +56,7 @@ void *TCharmGetUserdata(int id);
 void TCharmMigrate(void);
 void TCharmDone(void);
 
+
 #ifdef __cplusplus
 };
 #endif
index 2b9443e5b4ff8edf30fc207ebe937f6c2a721aa5..41b2888241007466686fa3ea1d68cb7843904525 100644 (file)
@@ -9,3 +9,6 @@
        external tcharm_register
        external tcharm_migrate
        external tcharm_done
+
+       external tcharm_readonly_globals
+