00001
00002
00011 #ifndef SIM_H
00012 #define SIM_H
00013 #include "sim.decl.h"
00014 #include <stdarg.h>
00015
00016 void POSE_prepExit(void *param, void *msg);
00017 extern CProxy_sim POSE_Objects;
00018 extern CProxy_sim POSE_Objects_RO;
00019 extern CkChareID POSE_Coordinator_ID;
00020 extern POSE_Config pose_config;
00021 class sim;
00022
00024
00028 class eventMsg : public CMessage_eventMsg {
00029 public:
00031 POSE_TimeType timestamp;
00033 eventID evID;
00035 size_t msgSize;
00037 sim *parent;
00039 strat *str;
00041 double rst;
00043 eventMsg() { rst = 0.0; parent = NULL; str = NULL; evID.init();}
00045 virtual ~eventMsg() { }
00046 inline void sanitize() {
00047 CkAssert(timestamp > -1);
00048 CkAssert(evID.getPE() > -1);
00049 CkAssert(evID.getPE() < CkNumPes());
00050 CkAssert(parent == NULL);
00051 CkAssert(str == NULL);
00052 CkAssert(msgSize >= 0);
00053 }
00055
00058 inline void Timestamp(POSE_TimeType t) {
00059 timestamp = t;
00060 if (evID.getPE() == -1)
00061 evID = GetEventID();
00062 setPriority(t-POSE_TimeMax);
00063 rst = 0.0;
00064 parent = NULL; str = NULL;
00065 }
00066 inline void SetSequenceNumber(int ctrl) {
00067 evID = GetEventID();
00068 evID.setControl(ctrl);
00069 }
00071 inline eventMsg& operator=(const eventMsg& obj) {
00072 timestamp = obj.timestamp;
00073 evID = obj.evID;
00074 parent = obj.parent;
00075 str = obj.str;
00076
00077 rst = obj.rst;
00078 setPriority(timestamp-POSE_TimeMax);
00079 return *this;
00080 }
00082
00083 void *operator new (size_t size) {
00084 #ifndef SEQUENTIAL_POSE
00085 #ifdef MSG_RECYCLING
00086 MemoryPool *localPool = (MemoryPool *)CkLocalBranch(MemPoolID);
00087 if (localPool->CheckPool(size) > 0)
00088 return localPool->GetBlock(size);
00089 else {
00090 #endif
00091 #endif
00092 void *msg = CkAllocMsg(CMessage_eventMsg::__idx, size, 8*sizeof(POSE_TimeType));
00093 ((eventMsg *)msg)->msgSize = size;
00094 return msg;
00095 #ifndef SEQUENTIAL_POSE
00096 #ifdef MSG_RECYCLING
00097 }
00098 #endif
00099 #endif
00100 }
00101 inline void operator delete(void *p) {
00102 #ifndef SEQUENTIAL_POSE
00103 #ifdef MSG_RECYCLING
00104 MemoryPool *localPool = (MemoryPool *)CkLocalBranch(MemPoolID);
00105 int ps = localPool->CheckPool(((eventMsg *)p)->msgSize);
00106 if ((ps < MAX_POOL_SIZE) && (ps > -1)) {
00107 size_t msgSize = ((eventMsg *)p)->msgSize;
00108 memset(p, 0, msgSize);
00109 ((eventMsg *)p)->msgSize = msgSize;
00110 localPool->PutBlock(msgSize, p);
00111 }
00112 else
00113 #endif
00114 #endif
00115 CkFreeMsg(p);
00116 }
00118 inline void setPriority(POSE_TimeType prio) {
00119 #if USE_LONG_TIMESTAMPS
00120 memcpy(((POSE_TimeType *)CkPriorityPtr(this)),&prio,sizeof(POSE_TimeType));
00121 CkSetQueueing(this, CK_QUEUEING_LFIFO);
00122 #else
00123 *((int*)CkPriorityPtr(this)) = prio;
00124 CkSetQueueing(this, CK_QUEUEING_IFIFO);
00125 #endif
00126 }
00127 };
00128
00130 class cancelMsg : public CMessage_cancelMsg {
00131 public:
00133
00134 eventID evID;
00136
00137 POSE_TimeType timestamp;
00139 void *operator new (size_t size) {
00140 return CkAllocMsg(CMessage_cancelMsg::__idx, size, 8*sizeof(POSE_TimeType));
00141 }
00143 inline void operator delete(void *p) { CkFreeMsg(p); }
00145 inline void setPriority(POSE_TimeType prio) {
00146 #if USE_LONG_TIMESTAMPS
00147 memcpy(((POSE_TimeType *)CkPriorityPtr(this)),&prio,sizeof(POSE_TimeType));
00148 CkSetQueueing(this, CK_QUEUEING_LFIFO);
00149 #else
00150 *((int*)CkPriorityPtr(this)) = prio;
00151 CkSetQueueing(this, CK_QUEUEING_IFIFO);
00152 #endif
00153 }
00154
00155 };
00156
00158 class prioMsg : public CMessage_prioMsg {
00159 public:
00161 void *operator new (size_t size) {
00162 return CkAllocMsg(CMessage_eventMsg::__idx, size, 8*sizeof(POSE_TimeType));
00163 }
00165 inline void operator delete(void *p) { CkFreeMsg(p); }
00167 inline void setPriority(POSE_TimeType prio) {
00168 #if USE_LONG_TIMESTAMPS
00169 memcpy(((POSE_TimeType *)CkPriorityPtr(this)),&prio,sizeof(POSE_TimeType));
00170 CkSetQueueing(this, CK_QUEUEING_LFIFO);
00171 #else
00172 *((int*)CkPriorityPtr(this)) = prio;
00173 CkSetQueueing(this, CK_QUEUEING_IFIFO);
00174
00175 #endif
00176 }
00177 };
00178
00180 class destMsg : public CMessage_destMsg {
00181 public:
00182 int destPE;
00183 };
00184
00185
00187
00191 class sim : public CBase_sim {
00192 protected:
00194
00196 int active;
00197 public:
00199 eventQueue *eq;
00201 strat *myStrat;
00203 rep *objID;
00205 CancelList cancels;
00207 PVT *localPVT;
00209 int myPVTidx;
00211 int myLBidx;
00213
00214 int DOs;
00216
00217 int UNDOs;
00219 int sync;
00221 int *srVector;
00223 POSE_TimeType lastGVT;
00225
00226 double st, et, ct;
00227 #if !CMK_TRACE_DISABLED
00229 localStat *localStats;
00231
00232
00233
00234
00235
00236
00237
00238
00239 POSE_TimeType dop_override_evt;
00240 #endif
00242
00243
00244
00245 long long basicStats[2];
00247 LBgroup *localLBG;
00249 sim(void);
00250 sim(CkMigrateMessage *) {};
00252 virtual ~sim();
00254 void pup(PUP::er &p);
00256 void Step();
00258 void Step(prioMsg *m);
00260 void CheckpointStep(eventMsg *m);
00262 inline void Status() {
00263 localPVT->objUpdateOVT(myPVTidx, myStrat->SafeTime(), objID->OVT());
00264 }
00266 void Commit();
00268 void CheckpointCommit();
00270 void Cancel(cancelMsg *m);
00272 void ReportLBdata();
00274 inline void Migrate(destMsg *m) { migrateMe(m->destPE); }
00276 inline void Terminate() {
00277
00278
00279
00280
00281
00282 objID->terminus();
00283 contribute(2 * sizeof(long long), basicStats, CkReduction::sum_int, CkCallback(POSE_prepExit, NULL));
00284 }
00286 void SeqBeginCheckpoint();
00288 void SeqResumeAfterCheckpoint();
00290 void invokeStopEvent() {}
00292 void setSimulationStartGVT(POSE_TimeType startGVT) {
00293 objID->setSimulationStartGVT(startGVT);
00294 }
00296 inline int PVTindex() { return myPVTidx; }
00298 inline int IsActive() { return active; }
00300 inline void Activate() { active = 1; }
00302 inline void Deactivate() { active = 0; }
00304
00306 virtual void ResolveFn(int fnIdx, void *msg) { }
00308
00311 virtual void ResolveCommitFn(int fnIdx, void *msg) { }
00313 inline void registerSent(POSE_TimeType timestamp) {
00314 localPVT->objUpdate(timestamp, SEND);
00315 }
00317
00318 void CommitPrintf(const char *Fmt, ...) {
00319 va_list ap;
00320 va_start(ap,Fmt);
00321 InternalCommitPrintf(Fmt, ap);
00322 va_end(ap);
00323 }
00325
00326 void CommitError(const char *Fmt, ...) {
00327 va_list ap;
00328 va_start(ap,Fmt);
00329 InternalCommitPrintf(Fmt, ap);
00330 va_end(ap);
00331 myStrat->currentEvent->commitErr = 1;
00332 }
00333 void ResumeFromSync(void);
00335 void dump();
00336 private:
00338 void InternalCommitPrintf (const char *Fmt, va_list ap) {
00339 char *tmp;
00340 size_t tmplen=myStrat->currentEvent->commitBfrLen + strlen(Fmt) + 1 +512;
00341 if (!(tmp = (char *)malloc(tmplen * sizeof(char)))) {
00342 CkPrintf("ERROR: sim::CommitPrintf: OUT OF MEMORY!\n");
00343 CkExit();
00344 }
00345 if (myStrat->currentEvent->commitBfr && myStrat->currentEvent->commitBfrLen) {
00346 strcpy(tmp, myStrat->currentEvent->commitBfr);
00347 free(myStrat->currentEvent->commitBfr);
00348 vsnprintf(tmp+strlen(tmp), tmplen, Fmt, ap);
00349 }
00350 else vsnprintf(tmp, tmplen, Fmt, ap);
00351 myStrat->currentEvent->commitBfrLen = strlen(tmp) + 1;
00352 myStrat->currentEvent->commitBfr = tmp;
00353 }
00354 };
00355
00356 #endif
00357
00358
00359
00360
00361
00362
00363
00364
00365