00001
00005 #ifndef _ENVELOPE_H
00006 #define _ENVELOPE_H
00007
00008 #ifndef CkIntbits
00009 #define CkIntbits (sizeof(int)*8)
00010 #endif
00011
00012 #if CMK_ERROR_CHECKING
00013 #define _SET_USED(env, x) (env)->setUsed((x))
00014 #define _CHECK_USED(env) do { if(env->isUsed()) \
00015 CmiAbort("Message being re-sent. Aborting...\n"); \
00016 } while(0)
00017 #else
00018 #define _SET_USED(env, x) do{}while(0)
00019 #define _CHECK_USED(env) do{}while(0)
00020 #endif
00021
00022 #define CkMsgAlignmentMask (sizeof(double)-1)
00023 #define CkMsgAlignLength(x) (((x)+CkMsgAlignmentMask)&(~(CkMsgAlignmentMask)))
00024 #define CkMsgAlignOffset(x) (CkMsgAlignLength(x)-(x))
00025 #define CkPriobitsToInts(nBits) ((nBits+CkIntbits-1)/CkIntbits)
00026
00027 #define PW(x) CkPriobitsToInts(x)
00028
00029
00030
00031
00032
00043 class PathHistoryEnvelope {
00044 protected:
00045
00046 int sender_history_table_idx;
00047 double totalTime;
00048 public:
00049 double getTotalTime() const{ return totalTime; }
00050 int get_sender_history_table_idx() const{ return sender_history_table_idx; }
00051 void set_sender_history_table_idx(int i) { sender_history_table_idx = i; }
00052 PathHistoryEnvelope(){
00053 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
00054 reset();
00055 #endif
00056 }
00057 double getTime() const{ return totalTime; }
00058 void setTime(double t){ totalTime = t; }
00059 void pup(PUP::er &p) {
00060 p | sender_history_table_idx;
00061 p | totalTime;
00062 }
00063 void reset();
00064 void print() const;
00066 void printHTMLToString(char* buf) const{
00067 buf[0] = '\0';
00068 sprintf(buf+strlen(buf), "Path Time=%lf<br> Sender idx=%d", (double)totalTime, (int)sender_history_table_idx);
00069 }
00071 int getNumUsed() const;
00073 int getUsedCount(int idx) const;
00075 int getUsedEp(int idx) const;
00076 int getEpCount(int ep) const;
00077 void incrementTotalTime(double time);
00078
00079 void setDebug100();
00080 };
00085 typedef unsigned int UInt;
00086 typedef unsigned short UShort;
00087 typedef unsigned char UChar;
00088
00089 #include "charm.h"
00090 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00091 #include "ckobjid.h"
00092 #endif
00093
00098 CkpvExtern(int, envelopeEventID);
00099
00137 class envelope {
00138 private:
00140 char core[CmiReservedHeaderSize];
00141 public:
00148 union u_type {
00149 struct s_chare {
00150 void *ptr;
00151 UInt forAnyPe;
00152 int bype;
00153 } chare;
00154 struct s_group {
00155 CkGroupID g;
00156 CkNodeGroupID rednMgr;
00157 CkGroupID dep;
00158 int epoch;
00159 UShort arrayEp;
00160 } group;
00161 struct s_array{
00162 CkArrayIndexBase index;
00163 int listenerData[CK_ARRAYLISTENER_MAXLEN];
00164 CkGroupID arr;
00165 UChar hopCount;
00166 UChar ifNotThere;
00167 } array;
00168 struct s_roData {
00169 UInt count;
00170 } roData;
00171 struct s_roMsg {
00172 UInt roIdx;
00173 } roMsg;
00174 };
00175 struct s_attribs {
00176 UChar msgIdx;
00177 UChar mtype;
00178 UChar queueing:4;
00179 UChar isPacked:1;
00180 UChar isUsed:1;
00181 };
00182 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00183 CkObjID sender;
00184 CkObjID recver;
00185 MCount SN;
00186 MCount TN;
00187 int incarnation;
00188 MlogEntry *localMlogEntry;
00189 bool freeMsg;
00190 #endif
00191 private:
00192 u_type type;
00193 CMK_REFNUM_TYPE ref;
00194 s_attribs attribs;
00195 UChar align[CkMsgAlignOffset(CmiReservedHeaderSize+sizeof(u_type)+sizeof(CMK_REFNUM_TYPE)+sizeof(s_attribs))];
00196
00197
00198 UShort priobits;
00199 UShort epIdx;
00200 UInt pe;
00201 UInt event;
00202 UInt totalsize;
00203
00204 public:
00205 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00206 UInt piggyBcastIdx;
00207 #endif
00208 void pup(PUP::er &p);
00209 UInt getEvent(void) const { return event; }
00210 void setEvent(const UInt e) { event = e; }
00211 CMK_REFNUM_TYPE getRef(void) const { return ref; }
00212 void setRef(const CMK_REFNUM_TYPE r) { ref = r; }
00213 UChar getQueueing(void) const { return attribs.queueing; }
00214 void setQueueing(const UChar q) { attribs.queueing=q; }
00215 UChar getMsgtype(void) const { return attribs.mtype; }
00216 void setMsgtype(const UChar m) { attribs.mtype = m; }
00217 #if CMK_ERROR_CHECKING
00218 UChar isUsed(void) { return attribs.isUsed; }
00219 void setUsed(const UChar u) { attribs.isUsed=u; }
00220 #else
00221 inline void setUsed(const UChar u) {}
00222 #endif
00223 UChar getMsgIdx(void) const { return attribs.msgIdx; }
00224 void setMsgIdx(const UChar idx) { attribs.msgIdx = idx; }
00225 UInt getTotalsize(void) const { return totalsize; }
00226 void setTotalsize(const UInt s) { totalsize = s; }
00227 UInt getUsersize(void) const { return totalsize - priobits - sizeof(envelope); }
00228 UChar isPacked(void) const { return attribs.isPacked; }
00229 void setPacked(const UChar p) { attribs.isPacked = p; }
00230 UShort getPriobits(void) const { return priobits; }
00231 void setPriobits(const UShort p) { priobits = p; }
00232 UShort getPrioWords(void) const { return CkPriobitsToInts(priobits); }
00233 UShort getPrioBytes(void) const { return getPrioWords()*sizeof(int); }
00234 void* getPrioPtr(void) const {
00235 return (void *)((char *)this + totalsize - getPrioBytes());
00236 }
00237 static envelope *alloc(const UChar type, const UInt size=0, const UShort prio=0)
00238 {
00239 CkAssert(type>=NewChareMsg && type<=ForArrayEltMsg);
00240 register UInt tsize = sizeof(envelope)+
00241 CkMsgAlignLength(size)+
00242 sizeof(int)*CkPriobitsToInts(prio);
00243 register envelope *env = (envelope *)CmiAlloc(tsize);
00244 #if CMK_REPLAYSYSTEM
00245
00246 memset(env, 0, sizeof(envelope));
00247 env->setEvent(++CkpvAccess(envelopeEventID));
00248 #endif
00249 env->setMsgtype(type);
00250 env->totalsize = tsize;
00251 env->priobits = prio;
00252 env->setPacked(0);
00253 env->type.group.dep.setZero();
00254 _SET_USED(env, 0);
00255 env->setRef(0);
00256 env->setEpIdx(0);
00257
00258 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
00259 env->pathHistory.reset();
00260 #endif
00261
00262 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00263 env->sender.type = TypeInvalid;
00264 env->recver.type = TypeInvalid;
00265 env->SN = 0;
00266 env->TN = 0;
00267 env->incarnation = -1;
00268 env->localMlogEntry = NULL;
00269 #endif
00270
00271 return env;
00272 }
00273 void reset() {
00274 #if CMK_REPLAYSYSTEM
00275 setEvent(++CkpvAccess(envelopeEventID));
00276 #endif
00277 type.group.dep.setZero();
00278 }
00279 UShort getEpIdx(void) const { return epIdx; }
00280 void setEpIdx(const UShort idx) { epIdx = idx; }
00281 UInt getSrcPe(void) const { return pe; }
00282 void setSrcPe(const UInt s) { pe = s; }
00283 static void setSrcPe(char *env, const UInt s) { ((envelope*)env)->setSrcPe(s); }
00284
00285
00286 UInt getCount(void) const {
00287 CkAssert(getMsgtype()==RODataMsg); return type.roData.count;
00288 }
00289 void setCount(const UInt c) {
00290 CkAssert(getMsgtype()==RODataMsg); type.roData.count = c;
00291 }
00292 UInt getRoIdx(void) const {
00293 CkAssert(getMsgtype()==ROMsgMsg); return type.roMsg.roIdx;
00294 }
00295 void setRoIdx(const UInt r) {
00296 CkAssert(getMsgtype()==ROMsgMsg); type.roMsg.roIdx = r;
00297 }
00298
00299
00300 UInt isForAnyPE(void) {
00301 CkAssert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg);
00302 return type.chare.forAnyPe;
00303 }
00304 void setForAnyPE(UInt f) {
00305 CkAssert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg);
00306 type.chare.forAnyPe = f;
00307 }
00308 void* getVidPtr(void) const {
00309 CkAssert(getMsgtype()==NewVChareMsg || getMsgtype()==ForVidMsg
00310 || getMsgtype()==FillVidMsg || getMsgtype()==DeleteVidMsg);
00311 return type.chare.ptr;
00312 }
00313 void setVidPtr(void *p) {
00314 CkAssert(getMsgtype()==NewVChareMsg || getMsgtype()==ForVidMsg
00315 || getMsgtype()==FillVidMsg || getMsgtype()==DeleteVidMsg);
00316 type.chare.ptr = p;
00317 }
00318 void* getObjPtr(void) const {
00319 CkAssert(getMsgtype()==ForChareMsg); return type.chare.ptr;
00320 }
00321 void setObjPtr(void *p) {
00322 CkAssert(getMsgtype()==ForChareMsg); type.chare.ptr = p;
00323 }
00324 UInt getByPe(void) {
00325 CkAssert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg);
00326 return type.chare.bype;
00327 }
00328 void setByPe(UInt pe) {
00329 CkAssert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg);
00330 type.chare.bype = pe;
00331 }
00332
00333
00334 CkGroupID getGroupNum(void) const {
00335 CkAssert(getMsgtype()==BocInitMsg || getMsgtype()==ForBocMsg
00336 || getMsgtype()==NodeBocInitMsg || getMsgtype()==ForNodeBocMsg);
00337 return type.group.g;
00338 }
00339 void setGroupNum(const CkGroupID g) {
00340 CkAssert(getMsgtype()==BocInitMsg || getMsgtype()==ForBocMsg
00341 || getMsgtype()==NodeBocInitMsg || getMsgtype()==ForNodeBocMsg);
00342 type.group.g = g;
00343 }
00344 void setGroupEpoch(int epoch) { type.group.epoch=epoch; }
00345 int getGroupEpoch(void) { return type.group.epoch; }
00346 void setRednMgr(CkNodeGroupID r){ type.group.rednMgr = r; }
00347 CkNodeGroupID getRednMgr(){ return type.group.rednMgr; }
00348 CkGroupID getGroupDep(){ return type.group.dep; }
00349 void setGroupDep(const CkGroupID &r){ type.group.dep = r; }
00350
00351
00352 CkGroupID &getsetArrayMgr(void) {return type.array.arr;}
00353 int getArrayMgrIdx(void) const {return type.array.arr.idx;}
00354 UShort &getsetArrayEp(void) {return epIdx;}
00355 UShort &getsetArrayBcastEp(void) {return type.group.arrayEp;}
00356 UInt &getsetArraySrcPe(void) {return pe;}
00357 UChar &getsetArrayHops(void) {return type.array.hopCount;}
00358 int getArrayIfNotThere(void) {return type.array.ifNotThere;}
00359 void setArrayIfNotThere(int nt) {type.array.ifNotThere=nt;}
00360 int *getsetArrayListenerData(void) {return type.array.listenerData;}
00361 CkArrayIndex &getsetArrayIndex(void)
00362 {return *(CkArrayIndex *)&type.array.index;}
00363
00364 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
00365 public:
00369 PathHistoryEnvelope pathHistory;
00370 #endif
00371
00372 };
00373
00374
00375 inline envelope *UsrToEnv(const void *const msg) {
00376 return (((envelope *) msg)-1);
00377 }
00378
00379 inline void *EnvToUsr(const envelope *const env) {
00380 return ((void *)(env+1));
00381 }
00382
00383 inline envelope *_allocEnv(const int msgtype, const int size=0, const int prio=0) {
00384 return envelope::alloc(msgtype,size,prio);
00385 }
00386
00387 inline void *_allocMsg(const int msgtype, const int size, const int prio=0) {
00388 return EnvToUsr(envelope::alloc(msgtype,size,prio));
00389 }
00390
00391 inline void _resetEnv(envelope *env) {
00392 env->reset();
00393 }
00394
00395 inline void setEventID(envelope *env){
00396 env->setEvent(++CkpvAccess(envelopeEventID));
00397 }
00398
00401 extern UChar _defaultQueueing;
00402
00403 extern void CkPackMessage(envelope **pEnv);
00404 extern void CkUnpackMessage(envelope **pEnv);
00405
00406 class MsgPool: public SafePool<void *> {
00407 private:
00408 static void *_alloc(void) {
00409
00410 register envelope *env = _allocEnv(ForChareMsg,0,0);
00411 env->setQueueing(_defaultQueueing);
00412 env->setMsgIdx(0);
00413 return EnvToUsr(env);
00414 }
00415 static void _reset(void* m) {
00416 register envelope *env = UsrToEnv(m);
00417 _resetEnv(env);
00418 }
00419 public:
00420 MsgPool():SafePool<void*>(_alloc, CkFreeMsg, _reset) {}
00421 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00422 void *get(void){
00423 return allocfn();
00424 }
00425 void put(void *m){
00426 }
00427 #endif
00428 };
00429
00430 CkpvExtern(MsgPool*, _msgPool);
00431
00432 #endif