908ca6d66112706dc8cbbcc507dacbaf374d1d25
[charm.git] / src / ck-core / envelope.h
1 #ifndef _ENVELOPE_H
2 #define _ENVELOPE_H
3
4 #define CINTBITS (sizeof(int)*8)
5
6 #ifndef CMK_OPTIMIZE
7 #define _SET_USED(env, x) (env)->setUsed((x))
8 #define _CHECK_USED(env) if(env->isUsed()) { \
9                            CmiAbort("Message being re-sent. Aborting...\n"); \
10                          }
11 #else
12 #define _SET_USED(env, x)
13 #define _CHECK_USED(env)
14 #endif
15
16 typedef unsigned int   UInt;
17 typedef unsigned short UShort;
18 typedef unsigned char  UChar;
19
20 #define SVM1     (sizeof(void*)-1)
21 #define ALIGN(x) (((x)+SVM1)&(~(SVM1)))
22 #define A(x)     ALIGN(x)
23 #define D(x)     (A(x)-(x))
24 #define PW(x)    ((x+CINTBITS-1)/CINTBITS)
25
26 #define QMASK    0x0F
27 #define PMASK    0xF0
28
29 #define NewChareMsg    1
30 #define NewVChareMsg   2
31 #define BocInitMsg     3
32 #define ForChareMsg    4
33 #define ForBocMsg      5
34 #define ForVidMsg      6
35 #define FillVidMsg     7
36 #define DBocReqMsg     8
37 #define DBocNumMsg     9
38 #define RODataMsg      10
39 #define ROMsgMsg       11
40 #define ExitMsg        12
41 #define ReqStatMsg     13
42 #define StatMsg        14
43 #define NodeBocInitMsg 15
44 #define ForNodeBocMsg  16
45 #define DNodeBocReqMsg 17
46 #define DNodeBocNumMsg 18
47
48 // NewChareMsg : s1=epIdx
49 // NewVChareMsg: ptr=vidPtr, s1=epIdx
50 // ForChareMsg : ptr=objPtr, s1=epIdx
51 // ForVidMsg   : ptr=vidPtr, s1=epIdx
52 // FillVidMsg  : ptr=vidPtr
53 // BocInitMsg  : i1=groupnum, s1=epIdx
54 // DBocReqMsg  : ptr=usrmsg, s1=retEp
55 // DBocNumMsg  : ptr=usrmsg, i1=groupnum, s1=retEp
56 // RODataMsg   : i1=count
57 // ROMsgMsg    : i1=roIdx
58 // ForBocMsg   : i1=groupnum, s1=epidx
59 // NodeBocInitMsg: i1=groupnum, s1=epidx
60 // DNodeBocReqMsg: ptr=usrmsg, s1=retEp
61 // DNodeBocNumMsg: ptr=usrmsg, i1=groupnum, s1=retEp
62 // ForNodeBocMsg : i1=groupnum, s1=epIdx
63
64 class envelope {
65   private:
66     char   core[CmiExtHeaderSizeBytes];
67     void*  ptr;
68     UInt   event; // used by projections
69     UInt   pe;    // source processor
70     UInt   totalsize;
71     UInt   i1;
72     UShort s1;
73     UShort s2;
74     UShort priobits;
75     UChar  attribs1; // stores message type as well as the Used bit
76     UChar  attribs2; // stores queueing strategy as well as packed/unpacked
77     UChar  msgIdx;
78     // to make envelope void* aligned
79     UChar padding[D(3*sizeof(UShort)+3*sizeof(UChar))];
80   public:
81     UInt   getEvent(void) const { return event; }
82     void   setEvent(const UInt e) { event = e; }
83     UInt   getRef(void) const { return s2; }
84     void   setRef(const UShort r) { s2 = r; }
85     UChar  getQueueing(void) const { return (attribs2 & QMASK); }
86     void   setQueueing(const UChar q) { attribs2 = (attribs2 & PMASK) | q; }
87 #ifndef CMK_OPTIMIZE
88     UChar  getMsgtype(void) const { return (attribs1&0x7F); }
89     void   setMsgtype(const UChar m) { attribs1 = (attribs1&0x80) | m; }
90     UChar  isUsed(void) { return (attribs1&0x80); }
91     void   setUsed(const UChar u) { attribs1 = (attribs1 & 0x7F) | (u<<7); }
92 #else
93     UChar  getMsgtype(void) const { return attribs1; }
94     void   setMsgtype(const UChar m) { attribs1  = m; }
95 #endif
96     UChar  getMsgIdx(void) const { return msgIdx; }
97     void   setMsgIdx(const UChar idx) { msgIdx = idx; }
98     UInt   getTotalsize(void) const { return totalsize; }
99     void   setTotalsize(const UInt s) { totalsize = s; }
100     UChar  isPacked(void) const { return ((attribs2 & PMASK)>>4); }
101     void   setPacked(const UChar p) { attribs2 = (attribs2 & QMASK) | (p<<4); }
102     UShort getPriobits(void) const { return priobits; }
103     void   setPriobits(const UShort p) { priobits = p; }
104     UShort getPrioWords(void) const { return (priobits+CINTBITS-1)/CINTBITS; }
105     UShort getPrioBytes(void) const { return getPrioWords()*sizeof(int); }
106     void*  getPrioPtr(void) const { 
107       return (void *)((char *)this + totalsize - getPrioBytes());
108     }
109     UInt   getCount(void) const { assert(getMsgtype()==RODataMsg); return i1; }
110     void   setCount(const UInt c) { assert(getMsgtype()==RODataMsg); i1 = c; }
111     UInt   getRoIdx(void) const { assert(getMsgtype()==ROMsgMsg); return i1; }
112     void   setRoIdx(const UInt r) { assert(getMsgtype()==ROMsgMsg); i1 = r; }
113     static envelope *alloc(const UChar type, const UInt size=0, const UShort prio=0)
114     {
115       assert(type>=NewChareMsg && type<=DNodeBocNumMsg);
116       register UInt tsize = sizeof(envelope)+ALIGN(size)+sizeof(int)*PW(prio);
117       register envelope *env = (envelope *)CmiAlloc(tsize);
118       env->setMsgtype(type);
119       env->totalsize = tsize;
120       env->priobits = prio;
121       env->setPacked(0);
122       _SET_USED(env, 0);
123       return env;
124     }
125     UShort getEpIdx(void) const {
126       assert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg
127           || getMsgtype()==ForChareMsg || getMsgtype()==ForVidMsg
128           || getMsgtype()==BocInitMsg || getMsgtype()==NodeBocInitMsg
129           || getMsgtype()==ForBocMsg || getMsgtype()==ForNodeBocMsg);
130       return s1;
131     }
132     void   setEpIdx(const UShort idx) {
133       assert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg
134           || getMsgtype()==ForChareMsg || getMsgtype()==ForVidMsg
135           || getMsgtype()==BocInitMsg || getMsgtype()==NodeBocInitMsg
136           || getMsgtype()==ForBocMsg || getMsgtype()==ForNodeBocMsg);
137       s1 = idx;
138     }
139     UInt isForAnyPE(void) { 
140       assert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg); 
141       return i1; 
142     }
143     void setForAnyPE(UInt f) { 
144       assert(getMsgtype()==NewChareMsg || getMsgtype()==NewVChareMsg); 
145       i1 = f; 
146     }
147     void*  getVidPtr(void) const {
148       assert(getMsgtype()==NewVChareMsg || getMsgtype()==ForVidMsg
149           || getMsgtype()==FillVidMsg);
150       return ptr;
151     }
152     void   setVidPtr(void *p) {
153       assert(getMsgtype()==NewVChareMsg || getMsgtype()==ForVidMsg
154           || getMsgtype()==FillVidMsg);
155       ptr = p;
156     }
157     UInt   getSrcPe(void) const { return pe; }
158     void   setSrcPe(const UInt s) { pe = s; }
159     void*  getObjPtr(void) const { assert(getMsgtype()==ForChareMsg); return ptr; }
160     void   setObjPtr(void *p) { assert(getMsgtype()==ForChareMsg); ptr = p; }
161     UShort getRetEp(void) const {
162       assert(getMsgtype()==DBocReqMsg || getMsgtype()==DNodeBocReqMsg
163           || getMsgtype()==DBocNumMsg || getMsgtype()==DNodeBocNumMsg); 
164       return s1; 
165     }
166     void   setRetEp(const UShort e) {
167       assert(getMsgtype()==DBocReqMsg || getMsgtype()==DNodeBocReqMsg
168           || getMsgtype()==DBocNumMsg || getMsgtype()==DNodeBocNumMsg); 
169       s1 = e; 
170     }
171     void*  getUsrMsg(void) const { 
172       assert(getMsgtype()==DBocReqMsg || getMsgtype()==DBocNumMsg
173           || getMsgtype()==DNodeBocReqMsg || getMsgtype()==DNodeBocNumMsg); 
174       return ptr; 
175     }
176     void   setUsrMsg(void *p) { 
177       assert(getMsgtype()==DBocReqMsg || getMsgtype()==DBocNumMsg
178           || getMsgtype()==DNodeBocReqMsg || getMsgtype()==DNodeBocNumMsg); 
179       ptr = p; 
180     }
181     UInt   getGroupNum(void) const {
182       assert(getMsgtype()==BocInitMsg || getMsgtype()==ForBocMsg
183           || getMsgtype()==DBocNumMsg || getMsgtype()==NodeBocInitMsg
184           || getMsgtype()==ForNodeBocMsg || getMsgtype()==DNodeBocNumMsg);
185       return i1;
186     }
187     void   setGroupNum(const UInt g) {
188       assert(getMsgtype()==BocInitMsg || getMsgtype()==ForBocMsg
189           || getMsgtype()==DBocNumMsg || getMsgtype()==NodeBocInitMsg
190           || getMsgtype()==ForNodeBocMsg || getMsgtype()==DNodeBocNumMsg);
191       i1 = g;
192     }
193 };
194
195 static inline envelope *UsrToEnv(const void *const msg) {
196   return (((envelope *) msg)-1);
197 }
198
199 static inline void *EnvToUsr(const envelope *const env) {
200   return ((void *)(env+1));
201 }
202
203 static inline envelope *_allocEnv(const int msgtype, const int size=0, const int prio=0) {
204   return envelope::alloc(msgtype,size,prio);
205 }
206
207 static inline void *_allocMsg(const int msgtype, const int size, const int prio=0) {
208   return EnvToUsr(envelope::alloc(msgtype,size,prio));
209 }
210
211 extern UChar   _defaultQueueing;
212
213 #define MAXMSGS 32
214
215 class MsgPool {
216   private:
217     int num;
218     void *msgs[MAXMSGS];
219     static void *_alloc(void) {
220       register envelope *env = _allocEnv(ForChareMsg,0,0);
221       env->setQueueing(_defaultQueueing);
222       env->setMsgIdx(0);
223       return EnvToUsr(env);
224     }
225   public:
226     MsgPool();
227     void *get(void) {
228       return (num ? msgs[--num] : _alloc());
229     }
230     void put(void *m) {
231       if (num==MAXMSGS)
232         CkFreeMsg(m);
233       else
234         msgs[num++] = m;
235     }
236 };
237
238 CpvExtern(MsgPool*, _msgPool);
239
240 #endif