7e00249f3b622378bbf042cb367149838bad30f9
[charm.git] / src / ck-core / qd.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 #ifndef _QD_H
9 #define _QD_H
10
11 class QdMsg {
12   private:
13     int phase; // 0..2
14     union {
15       struct { /* none */ } p1;
16       struct { int created; int processed; } p2;
17       struct { /* none */ } p3;
18       struct { int dirty; } p4;
19     } u;
20         CkCallback cb;
21   public:
22     int getPhase(void) { return phase; }
23     void setPhase(int p) { phase = p; }
24     CkCallback getCb(void) { CkAssert(phase==0); return cb; }
25     void setCb(CkCallback cb_) { CkAssert(phase==0); cb = cb_; }
26     int getCreated(void) { CkAssert(phase==1); return u.p2.created; }
27     void setCreated(int c) { CkAssert(phase==1); u.p2.created = c; }
28     int getProcessed(void) { CkAssert(phase==1); return u.p2.processed; }
29     void setProcessed(int p) { CkAssert(phase==1); u.p2.processed = p; }
30     int getDirty(void) { CkAssert(phase==2); return u.p4.dirty; }
31     void setDirty(int d) { CkAssert(phase==2); u.p4.dirty = d; }
32 };
33
34 class QdCallback {
35   public:
36         CkCallback cb;
37   public:
38     QdCallback(int e, CkChareID c) : cb(e, c) {}
39         QdCallback(CkCallback cb_) : cb(cb_) {}
40 //    void send(void) { CkSendMsg(ep,CkAllocMsg(0,0,0),&cid); }
41     void send(void) {
42       // pretending pe 0 in blue gene mode, switch back after the call.
43       int old = CmiSwitchToPE(0);
44       cb.send(NULL);
45       CmiSwitchToPE(old);
46     }
47 };
48
49 class QdState {
50   private:
51     int stage; // 0..2
52     int oProcessed;
53     int mCreated, mProcessed;
54     int cCreated, cProcessed;
55     int cDirty;
56     int nReported;
57     PtrQ *callbacks;
58     int nChildren;
59     int parent;
60     int *children;
61   public:
62     QdState():stage(0),mCreated(0),mProcessed(0),nReported(0) {
63       cCreated = 0; cProcessed = 0; cDirty = 0;
64       oProcessed = 0;
65       callbacks = new PtrQ();
66       _MEMCHECK(callbacks);
67       nChildren = CmiNumSpanTreeChildren(CmiMyPe());
68       parent = CmiSpanTreeParent(CmiMyPe());
69       if (nChildren != 0) {
70         children = new int[nChildren];
71         _MEMCHECK(children);
72         CmiSpanTreeChildren(CmiMyPe(), children);
73       }
74     }
75     void propagate(QdMsg *msg) {
76       envelope *env = UsrToEnv((void *)msg);
77       CmiSetHandler(env, _qdHandlerIdx);
78       for(int i=0; i<nChildren; i++) {
79 #if CMK_BLUEGENE_CHARM
80         CmiSyncSendFn(children[i], env->getTotalsize(), (char *)env);
81 #else
82         CmiSyncSend(children[i], env->getTotalsize(), (char *)env);
83 #endif
84       }
85     }
86     int getParent(void) { return parent; }
87     QdCallback *deq(void) { return (QdCallback*) callbacks->deq(); }
88     void enq(QdCallback *c) { callbacks->enq((void *) c); }
89     void create(int n=1) { mCreated += n; }
90     void process(int n=1) { mProcessed += n; }
91     int getCreated(void) { return mCreated; }
92     int getProcessed(void) { return mProcessed; }
93     int getCCreated(void) { return cCreated; }
94     int getCProcessed(void) { return cProcessed; }
95     void subtreeCreate(int c) { cCreated += c; }
96     void subtreeProcess(int p) { cProcessed += p; }
97     int getStage(void) { return stage; }
98     void setStage(int p) { stage = p; }
99     void reported(void) { nReported++; }
100     int allReported(void) {return nReported==(nChildren+1);}
101     void reset(void) { nReported=0; cCreated=0; cProcessed=0; cDirty=0; }
102     void markProcessed(void) { oProcessed = mProcessed; }
103     int isDirty(void) { return ((mProcessed > oProcessed) || cDirty); }
104     void subtreeSetDirty(int d) { cDirty = cDirty || d; }
105     void flushStates() {
106       stage = mCreated = mProcessed = nReported = 0;
107       cCreated = 0; cProcessed = 0; cDirty = 0;
108       oProcessed = 0;
109     }
110 };
111
112 extern void _qdHandler(envelope *);
113 CpvExtern(QdState*, _qd);
114
115 #endif