2d7797fa6e9dc20fc0faf2ba11ec766e781932e4
[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 QdCommMsg {
35   public:
36     int flag;     //  0: create   1: process
37     int count;
38 };
39
40 class QdCallback {
41   public:
42         CkCallback cb;
43   public:
44     QdCallback(int e, CkChareID c) : cb(e, c) {}
45         QdCallback(CkCallback cb_) : cb(cb_) {}
46 //    void send(void) { CkSendMsg(ep,CkAllocMsg(0,0,0),&cid); }
47     void send(void) {
48       // pretending pe 0 in blue gene mode, switch back after the call.
49       int old = CmiSwitchToPE(0);
50       cb.send(NULL);
51       CmiSwitchToPE(old);
52     }
53 };
54
55 class QdState {
56   private:
57     int stage; // 0..2
58     int oProcessed;
59     int mCreated, mProcessed;
60     int cCreated, cProcessed;
61     int cDirty;
62     int nReported;
63     PtrQ *callbacks;
64     int nChildren;
65     int parent;
66     int *children;
67   public:
68     QdState():stage(0),mCreated(0),mProcessed(0),nReported(0) {
69       cCreated = 0; cProcessed = 0; cDirty = 0;
70       oProcessed = 0;
71       callbacks = new PtrQ();
72       _MEMCHECK(callbacks);
73       nChildren = CmiNumSpanTreeChildren(CmiMyPe());
74       parent = CmiSpanTreeParent(CmiMyPe());
75       if (nChildren != 0) {
76         children = new int[nChildren];
77         _MEMCHECK(children);
78         CmiSpanTreeChildren(CmiMyPe(), children);
79       }
80       /* CmiPrintf("[%d] n:%d parent:%d - %d %d %d %d %d %d.\n", CmiMyPe(), nChildren, parent, nChildren?children[0]:-1, nChildren?children[1]:-1, nChildren?children[2]:-1, nChildren?children[3]:-1, nChildren?children[4]:-1, nChildren?children[5]:-1); */
81     }
82     void propagate(QdMsg *msg) {
83       envelope *env = UsrToEnv((void *)msg);
84       CmiSetHandler(env, _qdHandlerIdx);
85       for(int i=0; i<nChildren; i++) {
86 #if CMK_BLUEGENE_CHARM
87         CmiSyncSendFn(children[i], env->getTotalsize(), (char *)env);
88 #else
89         CmiSyncSend(children[i], env->getTotalsize(), (char *)env);
90 #endif
91       }
92     }
93     int getParent(void) { return parent; }
94     QdCallback *deq(void) { return (QdCallback*) callbacks->deq(); }
95     void enq(QdCallback *c) { callbacks->enq((void *) c); }
96     void create(int n=1) { 
97         mCreated += n; 
98 #if CK_MSG_IMMEDIATE
99         sendCount(0, n);
100 #endif
101     }
102     void sendCount(int flag, int count);     // send msg to rank 0 for counting
103     void process(int n=1) { 
104          mProcessed += n; 
105     }
106     int getCreated(void) { return mCreated; }
107     int getProcessed(void) { return mProcessed; }
108     int getCCreated(void) { return cCreated; }
109     int getCProcessed(void) { return cProcessed; }
110     void subtreeCreate(int c) { cCreated += c; }
111     void subtreeProcess(int p) { cProcessed += p; }
112     int getStage(void) { return stage; }
113     void setStage(int p) { stage = p; }
114     void reported(void) { nReported++; }
115     int allReported(void) {return nReported==(nChildren+1);}
116     void reset(void) { nReported=0; cCreated=0; cProcessed=0; cDirty=0; }
117     void markProcessed(void) { oProcessed = mProcessed; }
118     int isDirty(void) { return ((mProcessed > oProcessed) || cDirty); }
119     void subtreeSetDirty(int d) { cDirty = cDirty || d; }
120     void flushStates() {
121       stage = mCreated = mProcessed = nReported = 0;
122       cCreated = 0; cProcessed = 0; cDirty = 0;
123       oProcessed = 0;
124     }
125 };
126
127 extern void _qdHandler(envelope *);
128 extern void _qdCommHandler(envelope *);
129 CpvExtern(QdState*, _qd);
130
131 #endif