00001
00005 #ifndef _ENVELOPE_H
00006 #define _ENVELOPE_H
00007
00008 #include <pup.h>
00009 #include <charm.h>
00010 #include <middle.h>
00011 #include <cklists.h>
00012 #include <objid.h>
00013
00014 #ifndef CkIntbits
00015 #define CkIntbits (sizeof(int)*8)
00016 #endif
00017
00018 #if CMK_ERROR_CHECKING
00019 #define _SET_USED(env, x) (env)->setUsed((x))
00020 #define _CHECK_USED(env) do { if(env->isUsed()) \
00021 CmiAbort("Message being re-sent. Aborting...\n"); \
00022 } while(0)
00023 #else
00024 #define _SET_USED(env, x) do{}while(0)
00025 #define _CHECK_USED(env) do{}while(0)
00026 #endif
00027
00028 #define CkMsgAlignLength(x) ALIGN_DEFAULT(x)
00029 #define CkMsgAlignOffset(x) (CkMsgAlignLength(x)-(x))
00030 #define CkPriobitsToInts(nBits) ((nBits+CkIntbits-1)/CkIntbits)
00031
00032 #if CMK_MESSAGE_LOGGING
00033 #define CK_FREE_MSG_MLOG 0x1
00034 #define CK_BYPASS_DET_MLOG 0x2
00035 #define CK_MULTICAST_MSG_MLOG 0x4
00036 #define CK_REDUCTION_MSG_MLOG 0x8
00037 #endif
00038
00049 class PathHistoryEnvelope {
00050 protected:
00051
00052 int sender_history_table_idx;
00053 double totalTime;
00054 public:
00055 double getTotalTime() const{ return totalTime; }
00056 int get_sender_history_table_idx() const{ return sender_history_table_idx; }
00057 void set_sender_history_table_idx(int i) { sender_history_table_idx = i; }
00058 PathHistoryEnvelope(){
00059 reset();
00060 }
00061 double getTime() const{ return totalTime; }
00062 void setTime(double t){ totalTime = t; }
00063 void pup(PUP::er &p) {
00064 p | sender_history_table_idx;
00065 p | totalTime;
00066 }
00067 void reset();
00068 void print() const;
00070 void printHTMLToString(char* buf) const{
00071 buf[0] = '\0';
00072 sprintf(buf+strlen(buf), "Path Time=%lf<br> Sender idx=%d", (double)totalTime, (int)sender_history_table_idx);
00073 }
00075 int getNumUsed() const;
00077 int getUsedCount(int idx) const;
00079 int getUsedEp(int idx) const;
00080 int getEpCount(int ep) const;
00081 void incrementTotalTime(double time);
00082
00083 void setDebug100();
00084 };
00089 typedef unsigned int UInt;
00090 typedef unsigned short UShort;
00091 typedef unsigned char UChar;
00092
00093 #include "charm.h"
00094 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00095 #include "ckobjid.h"
00096 #endif
00097
00102 CkpvExtern(int, envelopeEventID);
00103
00142 namespace ck {
00143
00144 namespace impl {
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 int epoch;
00158 UShort arrayEp;
00159 } group;
00160 struct s_array{
00161 CmiUInt8 id;
00162 CkGroupID arr;
00163 #if CMK_SMP_TRACE_COMMTHREAD
00164 UInt srcpe;
00165 #endif
00166 UChar hopCount;
00167 UChar ifNotThere;
00168 } array;
00169 struct s_roData {
00170 UInt count;
00171 } roData;
00172 struct s_roMsg {
00173 UInt roIdx;
00174 } roMsg;
00175 };
00176
00177 struct s_attribs {
00178 UChar msgIdx;
00179 UChar mtype;
00180 UChar queueing:4;
00181 UChar isPacked:1;
00182 UChar isUsed:1;
00183 UChar isVarSysMsg:1;
00184 };
00185
00186 }
00187 }
00188
00189 #if (defined(_FAULT_MLOG_) && !defined(_FAULT_CAUSAL_))
00190 #define CMK_ENVELOPE_FT_FIELDS \
00191 CkObjID sender; \
00192 CkObjID recver; \
00193 MCount SN; \
00194 int incarnation; \
00195 int flags; \
00196 UInt piggyBcastIdx;
00197 #elif defined(_FAULT_CAUSAL_)
00198 #define CMK_ENVELOPE_FT_FIELDS \
00199 CkObjID sender; \
00200 CkObjID recver; \
00201 MCount SN; \
00202 MCount TN; \
00203 int incarnation; \
00204 int flags; \
00205 UInt piggyBcastIdx;
00206 #else
00207 #define CMK_ENVELOPE_FT_FIELDS
00208 #endif
00209
00210 #if CMK_REPLAYSYSTEM || CMK_TRACE_ENABLED
00211 #define CMK_ENVELOPE_OPTIONAL_FIELDS \
00212 UInt event;
00213 #else
00214 #define CMK_ENVELOPE_OPTIONAL_FIELDS
00215 #endif
00216
00217 #define CMK_ENVELOPE_FIELDS \
00218 \
00219 char core[CmiReservedHeaderSize]; \
00220 UInt pe; \
00221 ck::impl::u_type type; \
00222 UInt totalsize; \
00223 CMK_ENVELOPE_OPTIONAL_FIELDS \
00224 CMK_REFNUM_TYPE ref; \
00225 UShort priobits; \
00226 UShort groupDepNum; \
00227 UShort epIdx; \
00228 ck::impl::s_attribs attribs;
00229
00230 class envelope {
00231 private:
00232
00233 class envelopeSizeHelper {
00234 CMK_ENVELOPE_FIELDS
00235 CMK_ENVELOPE_FT_FIELDS
00236 };
00237
00238 #ifdef __clang__
00239 #pragma GCC diagnostic push
00240 #pragma GCC diagnostic ignored "-Wunused-private-field"
00241 #endif
00242 CMK_ENVELOPE_FIELDS
00243 #ifdef __clang__
00244 #pragma GCC diagnostic pop
00245 #endif
00246
00247 public:
00248
00249 CMK_ENVELOPE_FT_FIELDS
00250
00251 #if defined(__GNUC__) || defined(__clang__)
00252 #pragma GCC diagnostic push
00253 #pragma GCC diagnostic ignored "-Wpedantic"
00254 #if defined(__clang__)
00255 #pragma GCC diagnostic ignored "-Wunused-private-field"
00256 #endif
00257 #endif
00258
00259 UChar align[CkMsgAlignOffset(sizeof(envelopeSizeHelper))];
00260 #if defined(__GNUC__) || defined(__clang__)
00261 #pragma GCC diagnostic pop
00262 #endif
00263
00264 void pup(PUP::er &p);
00265 #if CMK_REPLAYSYSTEM || CMK_TRACE_ENABLED
00266 UInt getEvent(void) const { return event; }
00267 void setEvent(const UInt e) { event = e; }
00268 #endif
00269 CMK_REFNUM_TYPE getRef(void) const { return ref; }
00270 void setRef(const CMK_REFNUM_TYPE r) { ref = r; }
00271 UChar getQueueing(void) const { return attribs.queueing; }
00272 void setQueueing(const UChar q) { attribs.queueing=q; }
00273 UChar getMsgtype(void) const { return attribs.mtype; }
00274 void setMsgtype(const UChar m) { attribs.mtype = m; }
00275 #if CMK_ERROR_CHECKING
00276 UChar isUsed(void) const { return attribs.isUsed; }
00277 void setUsed(const UChar u) { attribs.isUsed=u; }
00278 #else
00279 inline void setUsed(const UChar u) {}
00280 #endif
00281 UChar getMsgIdx(void) const { return attribs.msgIdx; }
00282 void setMsgIdx(const UChar idx) { attribs.msgIdx = idx; }
00283 UInt getTotalsize(void) const { return totalsize; }
00284 void setTotalsize(const UInt s) { totalsize = s; }
00285 UInt getUsersize(void) const {
00286 return totalsize - getGroupDepSize() - getPrioBytes() - sizeof(envelope);
00287 }
00288 void setUsersize(const UInt s) {
00289 if (s == getUsersize()) {
00290 return;
00291 }
00292 CkAssert(s < getUsersize());
00293 UInt newPrioOffset = sizeof(envelope) + CkMsgAlignLength(s);
00294 UInt newTotalsize = newPrioOffset + getPrioBytes() + getGroupDepSize();
00295 void *newPrioPtr = (void *) ((char *) this + newPrioOffset);
00296
00297 memmove(newPrioPtr, getPrioPtr(), getPrioBytes());
00298 setTotalsize(newTotalsize);
00299 }
00300
00301
00302 void shrinkUsersize(const UInt s) {
00303 CkAssert(s <= getUsersize());
00304 setUsersize(getUsersize() - s);
00305 }
00306
00307 UChar isPacked(void) const { return attribs.isPacked; }
00308 void setPacked(const UChar p) { attribs.isPacked = p; }
00309 UChar isVarSysMsg(void) const { return attribs.isVarSysMsg; }
00310 void setIsVarSysMsg(const UChar d) { attribs.isVarSysMsg = d; }
00311 UShort getPriobits(void) const { return priobits; }
00312 void setPriobits(const UShort p) { priobits = p; }
00313 UShort getPrioWords(void) const { return CkPriobitsToInts(priobits); }
00314 UShort getPrioBytes(void) const { return getPrioWords()*sizeof(int); }
00315 void* getPrioPtr(void) const {
00316 return (void *)((char *)this + totalsize - getGroupDepSize() - getPrioBytes());
00317 }
00318 void* getGroupDepPtr(void) const {
00319 return (void *)((char *)this + totalsize - getGroupDepSize());
00320 }
00321 static envelope *alloc(const UChar type, const UInt size=0, const UShort prio=0, const GroupDepNum groupDepNumRequest=GroupDepNum{})
00322 {
00323 #if CMK_LOCKLESS_QUEUE
00324 CkAssert(type>=NewChareMsg && type<LAST_CK_ENVELOPE_TYPE);
00325 #else
00326 CkAssert(type>=NewChareMsg && type<=ForArrayEltMsg);
00327 #endif
00328 #if CMK_USE_STL_MSGQ
00329
00330 CkAssert(sizeof(CMK_MSG_PRIO_TYPE) >= sizeof(int)*CkPriobitsToInts(prio));
00331 #endif
00332
00333 UInt tsize = sizeof(envelope)+
00334 CkMsgAlignLength(size)+
00335 sizeof(int)*CkPriobitsToInts(prio) +
00336 sizeof(CkGroupID)*(int)groupDepNumRequest;
00337
00338
00339
00340 envelope *env = (envelope *)CmiAlloc(tsize);
00341 #if CMK_REPLAYSYSTEM
00342
00343 memset(env, 0, sizeof(envelope));
00344 env->setEvent(++CkpvAccess(envelopeEventID));
00345 #endif
00346 env->setMsgtype(type);
00347 env->totalsize = tsize;
00348 env->priobits = prio;
00349 env->setPacked(0);
00350 env->setGroupDepNum((int)groupDepNumRequest);
00351 _SET_USED(env, 0);
00352 env->setEpIdx(0);
00353 env->setIsVarSysMsg(0);
00354
00355 #if USE_CRITICAL_PATH_HEADER_ARRAY
00356 env->pathHistory.reset();
00357 #endif
00358
00359 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00360 env->sender.type = TypeInvalid;
00361 env->recver.type = TypeInvalid;
00362 env->SN = 0;
00363 env->flags = 0;
00364 #if defined(_FAULT_CAUSAL_)
00365 env->TN = 0;
00366 #endif
00367 env->incarnation = -1;
00368 #endif
00369
00370 return env;
00371 }
00372 void reset() {
00373 #if CMK_REPLAYSYSTEM
00374 setEvent(++CkpvAccess(envelopeEventID));
00375 #endif
00376 memset(getGroupDepPtr(), 0, getGroupDepSize());
00377 }
00378 UShort getEpIdx(void) const { return epIdx; }
00379 void setEpIdx(const UShort idx) { epIdx = idx; }
00380 UInt getSrcPe(void) const { return pe; }
00381 void setSrcPe(const UInt s) { pe = s; }
00382 static void setSrcPe(char *env, const UInt s) { ((envelope*)env)->setSrcPe(s); }
00383
00384
00385 UInt getCount(void) const {
00386 CkAssert(getMsgtype()==RODataMsg); return type.roData.count;
00387 }
00388 void setCount(const UInt c) {
00389 CkAssert(getMsgtype()==RODataMsg); type.roData.count = c;
00390 }
00391 UInt getRoIdx(void) const {
00392 CkAssert(getMsgtype()==ROMsgMsg); return type.roMsg.roIdx;
00393 }
00394 void setRoIdx(const UInt r) {
00395 CkAssert(getMsgtype()==ROMsgMsg); type.roMsg.roIdx = r;
00396 }
00397
00398
00399 UInt isForAnyPE(void) const {
00400 CkAssert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg);
00401 return type.chare.forAnyPe;
00402 }
00403 void setForAnyPE(UInt f) {
00404 CkAssert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg);
00405 type.chare.forAnyPe = f;
00406 }
00407 void* getVidPtr(void) const {
00408 CkAssert(getMsgtype()==NewVChareMsg || getMsgtype()==ForVidMsg
00409 || getMsgtype()==FillVidMsg || getMsgtype()==DeleteVidMsg);
00410 return type.chare.ptr;
00411 }
00412 void setVidPtr(void *p) {
00413 CkAssert(getMsgtype()==NewVChareMsg || getMsgtype()==ForVidMsg
00414 || getMsgtype()==FillVidMsg || getMsgtype()==DeleteVidMsg);
00415 type.chare.ptr = p;
00416 }
00417 void* getObjPtr(void) const {
00418 CkAssert(getMsgtype()==ForChareMsg); return type.chare.ptr;
00419 }
00420 void setObjPtr(void *p) {
00421 CkAssert(getMsgtype()==ForChareMsg); type.chare.ptr = p;
00422 }
00423 UInt getByPe(void) const {
00424 CkAssert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg);
00425 return type.chare.bype;
00426 }
00427 void setByPe(UInt pe) {
00428 CkAssert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg);
00429 type.chare.bype = pe;
00430 }
00431
00432
00433 CkGroupID getGroupNum(void) const {
00434 CkAssert(getMsgtype()==BocInitMsg || getMsgtype()==ForBocMsg
00435 || getMsgtype()==NodeBocInitMsg || getMsgtype()==ForNodeBocMsg);
00436 return type.group.g;
00437 }
00438 void setGroupNum(const CkGroupID g) {
00439 CkAssert(getMsgtype()==BocInitMsg || getMsgtype()==ForBocMsg
00440 || getMsgtype()==NodeBocInitMsg || getMsgtype()==ForNodeBocMsg);
00441 type.group.g = g;
00442 }
00443 void setGroupEpoch(int epoch) { CkAssert(getMsgtype()==BocInitMsg || getMsgtype()==NodeBocInitMsg); type.group.epoch=epoch; }
00444 int getGroupEpoch(void) const { CkAssert(getMsgtype()==BocInitMsg || getMsgtype()==NodeBocInitMsg); return type.group.epoch; }
00445 void setRednMgr(CkNodeGroupID r){ CkAssert(getMsgtype()==BocInitMsg || getMsgtype()==ForBocMsg
00446 || getMsgtype()==NodeBocInitMsg || getMsgtype()==ForNodeBocMsg);
00447 type.group.rednMgr = r; }
00448 CkNodeGroupID getRednMgr(){ CkAssert(getMsgtype()==BocInitMsg || getMsgtype()==ForBocMsg
00449 || getMsgtype()==NodeBocInitMsg || getMsgtype()==ForNodeBocMsg);
00450 return type.group.rednMgr; }
00451 UShort getGroupDepSize() const { return groupDepNum*sizeof(CkGroupID); }
00452 UShort getGroupDepNum() const { return groupDepNum; }
00453 void setGroupDepNum(const UShort &r) { groupDepNum = r; }
00454 CkGroupID getGroupDep(int index=0) { return *((CkGroupID *)getGroupDepPtr() + index); }
00455 void setGroupDep(const CkGroupID &r, int index=0) {
00456 *(((CkGroupID *)getGroupDepPtr())+ index) = r;
00457 }
00458
00459
00460 CkGroupID getArrayMgr(void) const {
00461 if (getMsgtype() == ForArrayEltMsg || getMsgtype() == ArrayEltInitMsg)
00462 return type.array.arr;
00463 else
00464 CkAbort("Cannot return ArrayID from msg for non-array entity");
00465
00466 return type.array.arr;
00467 }
00468 void setArrayMgr(const CkGroupID gid) { CkAssert(getMsgtype() == ForArrayEltMsg || getMsgtype() == ArrayEltInitMsg); type.array.arr = gid; }
00469 int getArrayMgrIdx(void) const {CkAssert(getMsgtype() == ForArrayEltMsg || getMsgtype() == ArrayEltInitMsg); return type.array.arr.idx;}
00470 UShort &getsetArrayEp(void) {return epIdx;}
00471 UShort &getsetArrayBcastEp(void) {return type.group.arrayEp;}
00472 #if CMK_SMP_TRACE_COMMTHREAD
00473 UInt &getsetArraySrcPe(void) {return type.array.srcpe;}
00474 #else
00475 UInt &getsetArraySrcPe(void) {return pe;}
00476 #endif
00477 UChar &getsetArrayHops(void) { CkAssert(getMsgtype() == ForArrayEltMsg || getMsgtype() == ArrayEltInitMsg); return type.array.hopCount;}
00478 int getArrayIfNotThere(void) const { CkAssert(getMsgtype() == ForArrayEltMsg || getMsgtype() == ArrayEltInitMsg); return type.array.ifNotThere;}
00479 void setArrayIfNotThere(int nt) { CkAssert(getMsgtype() == ForArrayEltMsg || getMsgtype() == ArrayEltInitMsg); type.array.ifNotThere=nt;}
00480
00481 void setRecipientID(ck::ObjID objid)
00482 {
00483 CkAssert(getMsgtype() == ForArrayEltMsg || getMsgtype() == ArrayEltInitMsg);
00484 type.array.id = objid.getID();
00485 }
00486
00487 CmiUInt8 getRecipientID() const
00488 {
00489 CkAssert(getMsgtype() == ForArrayEltMsg || getMsgtype() == ArrayEltInitMsg);
00490 return type.array.id;
00491 }
00492
00493 #if USE_CRITICAL_PATH_HEADER_ARRAY
00494 public:
00498 PathHistoryEnvelope pathHistory;
00499 #endif
00500
00501 };
00502
00503
00504 inline envelope *UsrToEnv(const void *const msg) {
00505 return (envelope *)((intptr_t)msg - sizeof(envelope));
00506 }
00507
00508 inline void *EnvToUsr(const envelope *const env) {
00509 return (void *)((intptr_t)env + sizeof(envelope));
00510 }
00511
00512 inline envelope *_allocEnv(const int msgtype, const int size=0, const int prio=0, const GroupDepNum groupDepNum=GroupDepNum{}) {
00513 return envelope::alloc(msgtype,size,prio,groupDepNum);
00514 }
00515
00516 inline void *_allocMsg(const int msgtype, const int size, const int prio=0, const GroupDepNum groupDepNum=GroupDepNum{}) {
00517 return EnvToUsr(envelope::alloc(msgtype,size,prio,groupDepNum));
00518 }
00519
00520 inline void _resetEnv(envelope *env) {
00521 env->reset();
00522 }
00523
00524 #if CMK_REPLAYSYSTEM
00525 inline void setEventID(envelope *env){
00526 env->setEvent(++CkpvAccess(envelopeEventID));
00527 }
00528 #endif
00529
00532 extern UChar _defaultQueueing;
00533
00534 extern void CkPackMessage(envelope **pEnv);
00535 extern void CkUnpackMessage(envelope **pEnv);
00536
00537 class MsgPool: public SafePool<void *> {
00538 private:
00539 static void *_alloc(void) {
00540
00541 envelope *env = _allocEnv(ForChareMsg,0,0,GroupDepNum{});
00542 env->setQueueing(_defaultQueueing);
00543 env->setMsgIdx(0);
00544 return EnvToUsr(env);
00545 }
00546 static void _reset(void* m) {
00547 envelope *env = UsrToEnv(m);
00548 _resetEnv(env);
00549 }
00550 public:
00551 MsgPool():SafePool<void*>(_alloc, CkFreeMsg, _reset) {}
00552 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
00553 void *get(void){
00554 return allocfn();
00555 }
00556 void put(void *m){
00557 }
00558 #endif
00559 };
00560
00561 CkpvExtern(MsgPool*, _msgPool);
00562
00563 #endif