00001 #ifndef _QD_H
00002 #define _QD_H
00003
00004 class QdMsg {
00005 private:
00006 int phase;
00007 union {
00008 struct { } p1;
00009 struct { int created; int processed; } p2;
00010 struct { } p3;
00011 struct { int dirty; } p4;
00012 } u;
00013 CkCallback cb;
00014 public:
00015 int getPhase(void) { return phase; }
00016 void setPhase(int p) { phase = p; }
00017 CkCallback getCb(void) { CkAssert(phase==0); return cb; }
00018 void setCb(CkCallback cb_) { CkAssert(phase==0); cb = cb_; }
00019 int getCreated(void) { CkAssert(phase==1); return u.p2.created; }
00020 void setCreated(int c) { CkAssert(phase==1); u.p2.created = c; }
00021 int getProcessed(void) { CkAssert(phase==1); return u.p2.processed; }
00022 void setProcessed(int p) { CkAssert(phase==1); u.p2.processed = p; }
00023 int getDirty(void) { CkAssert(phase==2); return u.p4.dirty; }
00024 void setDirty(int d) { CkAssert(phase==2); u.p4.dirty = d; }
00025 };
00026
00027 class QdCommMsg {
00028 public:
00029 int flag;
00030 int count;
00031 };
00032
00033 class QdCallback {
00034 public:
00035 CkCallback cb;
00036 public:
00037 QdCallback(int e, CkChareID c) : cb(e, c) {}
00038 QdCallback(CkCallback cb_) : cb(cb_) {}
00039
00040 void send(void) {
00041
00042 #if CMK_CONDS_USE_SPECIAL_CODE
00043 int old = CmiSwitchToPE(0);
00044 #endif
00045 cb.send(NULL);
00046 #if CMK_CONDS_USE_SPECIAL_CODE
00047 CmiSwitchToPE(old);
00048 #endif
00049 }
00050 };
00051
00052 class QdState {
00053 private:
00054 int stage;
00055 int oProcessed;
00056 int mCreated, mProcessed;
00057 int cCreated, cProcessed;
00058 int cDirty;
00059 int nReported;
00060 PtrQ *callbacks;
00061 int nChildren;
00062 int parent;
00063 int *children;
00064 public:
00065 QdState():stage(0),mCreated(0),mProcessed(0),nReported(0) {
00066 cCreated = 0; cProcessed = 0; cDirty = 0;
00067 oProcessed = 0;
00068 callbacks = new PtrQ();
00069 _MEMCHECK(callbacks);
00070 nChildren = CmiNumSpanTreeChildren(CmiMyPe());
00071 parent = CmiSpanTreeParent(CmiMyPe());
00072 if (nChildren != 0) {
00073 children = new int[nChildren];
00074 _MEMCHECK(children);
00075 CmiSpanTreeChildren(CmiMyPe(), children);
00076 }
00077
00078 }
00079 void propagate(QdMsg *msg) {
00080 envelope *env = UsrToEnv((void *)msg);
00081 CmiSetHandler(env, _qdHandlerIdx);
00082 for(int i=0; i<nChildren; i++) {
00083 #if CMK_BIGSIM_CHARM
00084 CmiSyncSendFn(children[i], env->getTotalsize(), (char *)env);
00085 #else
00086 CmiSyncSend(children[i], env->getTotalsize(), (char *)env);
00087 #endif
00088 }
00089 }
00090 int getParent(void) { return parent; }
00091 QdCallback *deq(void) { return (QdCallback*) callbacks->deq(); }
00092 void enq(QdCallback *c) { callbacks->enq((void *) c); }
00093 void create(int n=1) {
00094 mCreated += n;
00095 #if CK_MSG_IMMEDIATE
00096 sendCount(0, n);
00097 #endif
00098 }
00099 void sendCount(int flag, int count);
00100 void process(int n=1) {
00101 mProcessed += n;
00102 }
00103 int getCreated(void) { return mCreated; }
00104 int getProcessed(void) { return mProcessed; }
00105 int getCCreated(void) { return cCreated; }
00106 int getCProcessed(void) { return cProcessed; }
00107 void subtreeCreate(int c) { cCreated += c; }
00108 void subtreeProcess(int p) { cProcessed += p; }
00109 int getStage(void) { return stage; }
00110 void setStage(int p) { stage = p; }
00111 void reported(void) { nReported++; }
00112 int allReported(void) {return nReported==(nChildren+1);}
00113 void reset(void) { nReported=0; cCreated=0; cProcessed=0; cDirty=0; }
00114 void markProcessed(void) { oProcessed = mProcessed; }
00115 int isDirty(void) { return ((mProcessed > oProcessed) || cDirty); }
00116 void subtreeSetDirty(int d) { cDirty = cDirty || d; }
00117 void flushStates() {
00118 stage = mCreated = mProcessed = nReported = 0;
00119 cCreated = 0; cProcessed = 0; cDirty = 0;
00120 oProcessed = 0;
00121 }
00122 };
00123
00124 extern void _qdHandler(envelope *);
00125 extern void _qdCommHandler(envelope *);
00126 CpvExtern(QdState*, _qd);
00127
00128 #endif