
00001 /* 00002 Threaded Charm++ "Framework Framework" 00003 00004 This is the interface used by library writers-- 00005 people who use TCharm to build their own library. 00006 00007 Orion Sky Lawlor, olawlor@acm.org, 7/17/2002 00008 */ 00009 #ifndef __CHARM_TCHARMLIB_H 00010 #define __CHARM_TCHARMLIB_H 00011 00012 #include "ckcheckpoint.h" /* for CkStartCheckpoint */ 00013 00014 /* 00015 Library "fallback setup" routine. 00016 From an initcall, you register one of your routines 00017 here in case the user doesn't write a TCHARM_User_setup 00018 routine. Your fallback version sets up (only) your 00019 library by creating some TCharm threads with the appropriate 00020 "start running" routine, like this: 00021 00022 void myLibFallbackSetupFn(void) { 00023 TCHARM_Create(TCHARM_Get_num_chunks(),myLibUserStart); 00024 } 00025 00026 In case of multiple fallback setups, the last one wins. 00027 */ 00028 typedef void (*TCHARM_Fallback_setup_fn)(void); 00029 void TCHARM_Set_fallback_setup(TCHARM_Fallback_setup_fn f); 00030 00031 00032 00033 #ifndef FEM_ALONE 00034 00035 #include "tcharm_impl.h" 00036 00037 int TCHARM_Register_thread_function(TCHARM_Thread_data_start_fn fn); 00038 00039 /* 00040 This "start" call finds the currently running set of tcharm threads, 00041 copies their arrayID into retTCharmArray, and returns an 00042 opts object bound the the tcharm threads. In your library 00043 "Init" routine, you normally pass this opts object to your 00044 array's ckNew, then block until the startup is complete 00045 (often using TCharm::semaGet). 00046 */ 00047 CkArrayOptions TCHARM_Attach_start(CkArrayID *retTCharmArray,int *retNumElts=0); 00048 00049 /* Get the currently running TCharm threads: */ 00050 CkArrayID TCHARM_Get_threads(void); 00051 00053 void TCHARM_Suspend(void); 00054 00055 /* 00056 A simple client array that can be bound to a tcharm array. 00057 You write a TCharm library by inheriting your array from this class. 00058 You'll have to pass the TCharm arrayID to our constructor, and 00059 then call tcharmClientInit(). 00060 */ 00061 class TCharmClient1D : public ArrayElement1D { 00062 CProxy_TCharm threadProxy; //Proxy for our bound TCharm array 00063 protected: 00064 /* This is the actual TCharm object that manages our thread. 00065 You use this like "thread->suspend();", "thread->resume();", 00066 etc. 00067 */ 00068 TCharm *thread; 00069 inline void findThread(void) { 00070 thread=threadProxy[thisIndex].ckLocal(); 00071 if (thread==NULL) CkAbort("Can't locate TCharm thread!"); 00072 } 00073 00074 //Clients need to override this function to set their 00075 // thread-private variables. You usually use something like: 00076 // CtvAccessOther(forThread,_myFooPtr)=this; 00077 virtual void setupThreadPrivate(CthThread forThread) =0; 00078 00079 public: 00080 TCharmClient1D(const CkArrayID &threadArrayID) 00081 :threadProxy(threadArrayID) 00082 { 00083 //Argh! Can't call setupThreadPrivate yet, because 00084 // virtual functions don't work within constructors! 00085 findThread(); 00086 } 00087 TCharmClient1D(CkMigrateMessage *m) //Migration, etc. constructor 00088 { 00089 thread=NULL; 00090 } 00091 00092 //You MUST call this from your constructor: 00093 inline void tcharmClientInit(void) { 00094 setupThreadPrivate(thread->getThread()); 00095 } 00096 00097 virtual void ckJustMigrated(void); 00098 virtual void pup(PUP::er &p); 00099 }; 00100 00101 00102 /* 00103 Library API Calls. The pattern: 00104 TCHARM_API_TRACE("myRoutineName","myLibName"); 00105 MUST be put at the start of every user-callable library 00106 routine, to turn off isomalloc'd heaps before jumping 00107 into regular Charm. The string routineName is 00108 used for debugging printouts, with "+tcharm_trace myLibName". 00109 */ 00110 #define TCHARM_API_TRACE(routineName,libraryName) \ 00111 TCharmAPIRoutine apiRoutineSentry(routineName, libraryName) 00112 00113 00114 #else /* FEM_ALONE */ 00115 00116 # include "tcharmc.h" 00117 # define TCHARM_API_TRACE(routineName,libraryName) /* empty */ 00118 00119 #endif 00120 00121 #endif /*def(thisHeader)*/
1.5.5