00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __CHARM_TCHARM_IMPL_H
00011 #define __CHARM_TCHARM_IMPL_H
00012
00013 #include "pup.h"
00014 #include "pup_c.h"
00015 #include "charm-api.h"
00016 #include "tcharmc.h"
00017 #include "cklists.h"
00018 #include "memory-isomalloc.h"
00019
00020 class TCharmTraceLibList;
00021
00023 class callSystemStruct {
00024 public:
00025 const char *cmd;
00026 int *ret;
00027 };
00028 PUPbytes(callSystemStruct)
00029
00030
00031 #include "tcharm.decl.h"
00032
00033 class TCharm;
00034
00035
00036
00037
00038 class TCHARM_Thread_options {
00039 public:
00040 int stackSize;
00041 int exitWhenDone;
00042
00043 TCHARM_Thread_options(int doDefault);
00044 TCHARM_Thread_options() {}
00045
00046 void sanityCheck(void);
00047 };
00048
00049 class TCharmInitMsg : public CMessage_TCharmInitMsg {
00050 public:
00051
00052
00053 int threadFn;
00054
00055 TCHARM_Thread_options opts;
00056
00057 int numElements;
00058
00059 char *data;
00060
00061 TCharmInitMsg(int threadFn_,const TCHARM_Thread_options &opts_)
00062 :threadFn(threadFn_), opts(opts_) {}
00063 };
00064
00065
00066 CtvExtern(TCharm *,_curTCharm);
00067
00068 class TCharm: public CBase_TCharm
00069 {
00070 public:
00071
00072
00073 class UserData {
00074
00075 CthThread t;
00076 size_t pos;
00077 char mode;
00078 TCHARM_Pup_fn cfn;
00079 TCHARM_Pup_global_fn gfn;
00080 public:
00081 UserData(int i=0) {pos=0; mode='?'; cfn=NULL; gfn=NULL;}
00082 UserData(TCHARM_Pup_fn cfn_,CthThread t_,void *p)
00083 {cfn=cfn_; t=t_; pos=CthStackOffset(t, (char *)p); mode='c';}
00084 UserData(TCHARM_Pup_global_fn gfn_,CthThread t_,void *p)
00085 {gfn=gfn_; t=t_; pos=CthStackOffset(t, (char *)p); mode='g';}
00086 inline void *getData(void) const {return pos==0?NULL:CthPointer(t, pos);}
00087 void pup(PUP::er &p);
00088 void update(CthThread t_) { t=t_; }
00089 friend inline void operator|(PUP::er &p,UserData &d) {d.pup(p);}
00090 };
00091
00092 CkVec<UserData> sud;
00093
00094
00095 class TCharmSemaphore {
00096 public:
00097 int id;
00098 void *data;
00099 CthThread thread;
00100
00101 TCharmSemaphore() { id=-1; data=NULL; thread=NULL; }
00102 TCharmSemaphore(int id_) { id=id_; data=NULL; thread=NULL; }
00103 };
00105 CkVec<TCharmSemaphore> sema;
00106 TCharmSemaphore *findSema(int id);
00107 TCharmSemaphore *getSema(int id);
00108 void freeSema(TCharmSemaphore *);
00109
00112 void semaPut(int id,void *data);
00113
00115 void *semaPeek(int id);
00116
00119 void *semaGets(int id);
00120
00124 void *semaGet(int id);
00125
00126
00127 static void nodeInit(void);
00128 static void procInit(void);
00129 private:
00130
00131 class ThreadInfo {
00132 public:
00133 CProxy_TCharm tProxy;
00134 int thisElement;
00135 int numElements;
00136 };
00137
00138 TCharmInitMsg *initMsg;
00139 CthThread tid;
00140 friend class TCharmAPIRoutine;
00141 CmiIsomallocBlockList *heapBlocks;
00142 CtgGlobals threadGlobals;
00143 void pupThread(PUP::er &p);
00144
00145
00146
00147
00148 bool isStopped, resumeAfterMigration, exitWhenDone, isSelfDone, skipResume;
00149 ThreadInfo threadInfo;
00150 double timeOffset;
00151
00152
00153 enum {maxUserData=16};
00154 int nUd;
00155 UserData ud[maxUserData];
00156
00157 void ResumeFromSync(void);
00158
00159 public:
00160 TCharm(TCharmInitMsg *initMsg);
00161 TCharm(CkMigrateMessage *);
00162 ~TCharm();
00163
00164 virtual void ckJustMigrated(void);
00165 virtual void ckJustRestored(void);
00166 virtual void ckAboutToMigrate(void);
00167
00168 void migrateDelayed(int destPE);
00169 void atBarrier(CkReductionMsg *);
00170 void atExit(CkReductionMsg *);
00171 void clear();
00172
00173
00174 virtual void pup(PUP::er &p);
00175
00176
00177 void run(void);
00178
00179 inline double getTimeOffset(void) const { return timeOffset; }
00180
00181
00182
00183 void barrier(void);
00184
00185
00186 void migrateTo(int destPE);
00187
00188 void evacuate();
00189
00190
00191 void done(void);
00192
00193
00194 int add(const UserData &d);
00195 void *lookupUserData(int ud);
00196
00197 inline static TCharm *get(void) {
00198 TCharm *c=getNULL();
00199 #ifndef CMK_OPTIMIZE
00200 if (!c) ::CkAbort("TCharm has not been initialized!\n");
00201 #endif
00202 return c;
00203 }
00204 inline static TCharm *getNULL(void) {return CtvAccess(_curTCharm);}
00205 inline CthThread getThread(void) {return tid;}
00206 inline const CProxy_TCharm &getProxy(void) const {return threadInfo.tProxy;}
00207 inline int getElement(void) const {return threadInfo.thisElement;}
00208 inline int getNumElements(void) const {return threadInfo.numElements;}
00209
00210
00211 inline void stopTiming(void) {ckStopTiming();}
00212 inline void startTiming(void) {ckStartTiming();}
00213
00214
00215 void schedule(void);
00216
00217
00218 void stop(void);
00219 void start(void);
00220
00221 inline void suspend(void) {stop();}
00222 inline void resume(void) {
00223
00224 if (isStopped){
00225 start();
00226 }
00227 else {
00228
00229 }
00230 }
00231
00232
00233 void migrate(void);
00234 void async_migrate(void);
00235 void allow_migrate(void);
00236
00237
00238 static void activateThread(void) {
00239 TCharm *tc=CtvAccess(_curTCharm);
00240 if (tc!=NULL) {
00241 if (tc->heapBlocks)
00242 CmiIsomallocBlockListActivate(tc->heapBlocks);
00243 if (tc->threadGlobals)
00244 CtgInstall(tc->threadGlobals);
00245 }
00246 }
00247
00248 static void deactivateThread(void) {
00249 CmiIsomallocBlockListActivate(NULL);
00250 CtgInstall(NULL);
00251 }
00252 static void activateVariable(const void *ptr) {
00253 TCharm *tc=CtvAccess(_curTCharm);
00254 if (tc!=NULL) {
00255 if (tc->threadGlobals)
00256 CtgInstall_var(tc->threadGlobals, (char *)ptr);
00257 }
00258 }
00259 static void deactivateVariable(const void *ptr) {
00260 TCharm *tc=CtvAccess(_curTCharm);
00261 if (tc!=NULL) {
00262 if (tc->threadGlobals)
00263 CtgUninstall_var(tc->threadGlobals, (char *)ptr);
00264 }
00265 }
00266
00268 int system(const char *cmd);
00269 void callSystem(const callSystemStruct &s);
00270
00271 inline CthThread getTid() { return tid; }
00272 };
00273
00274 void TCHARM_Api_trace(const char *routineName, const char *libraryName);
00275
00276
00277
00278
00279
00280 class TCharmAPIRoutine {
00281 int state;
00282 CtgGlobals oldGlobals;
00283 #ifdef CMK_BIGSIM_CHARM
00284 void *callEvent;
00285 int pe;
00286 #endif
00287
00288 public:
00289
00290 TCharmAPIRoutine(const char *routineName, const char *libraryName)
00291 {
00292 #ifdef CMK_BIGSIM_CHARM
00293
00294
00295 _TRACE_BG_TLINE_END(&callEvent);
00296 _TRACE_BG_END_EXECUTE(0);
00297 pe = CmiMyPe();
00298 _TRACE_BG_BEGIN_EXECUTE_NOMSG(routineName, &callEvent, 0);
00299 #endif
00300
00301 state = 0;
00302
00303
00304
00305 if(CmiIsomallocBlockListCurrent() == NULL){
00306 state |= 0x1;
00307 }
00308 if(CtgCurrentGlobals() == NULL){
00309 state |= 0x10;
00310 }
00311
00312 TCharm::deactivateThread();
00313
00314 #ifndef CMK_OPTIMIZE
00315 TCHARM_Api_trace(routineName,libraryName);
00316 #endif
00317 }
00318
00319
00320 ~TCharmAPIRoutine() {
00321 CmiIsomallocBlockList *oldHeapBlock;
00322 TCharm *tc=CtvAccess(_curTCharm);
00323 if(tc != NULL){
00324 if(state & 0x1){
00325 oldHeapBlock = tc->heapBlocks;
00326 tc->heapBlocks = NULL;
00327 }
00328 if(state & 0x10){
00329 oldGlobals = tc->threadGlobals;
00330 tc->threadGlobals = NULL;
00331 }
00332 }
00333
00334
00335 TCharm::activateThread();
00336 if(tc != NULL){
00337 if(state & 0x1){
00338 tc->heapBlocks = oldHeapBlock;
00339 }
00340 if(state & 0x10){
00341 tc->threadGlobals = oldGlobals;
00342 }
00343 }
00344
00345 #ifdef CMK_BIGSIM_CHARM
00346 void *log;
00347 _TRACE_BG_TLINE_END(&log);
00348 _TRACE_BG_END_EXECUTE(0);
00349 _TRACE_BG_BEGIN_EXECUTE_NOMSG("user_code", &log, 0);
00350 if (CmiMyPe() == pe) _TRACE_BG_ADD_BACKWARD_DEP(callEvent);
00351 #endif
00352 }
00353 };
00354
00355
00356 #define TCHARMAPI(routineName) TCHARM_API_TRACE(routineName,"tcharm");
00357
00358
00359 FDECL void FTN_NAME(TCHARM_USER_NODE_SETUP,tcharm_user_node_setup)(void);
00360 FDECL void FTN_NAME(TCHARM_USER_SETUP,tcharm_user_setup)(void);
00361
00362
00363 #endif
00364
00365