LRTS Comm Thread Tracing in message recieve
[charm.git] / src / ck-core / register.h
blob46465506e355cdb69af026115053422dd5c7b679
1 /**
2 \file
3 \brief Charm++: Lists of possible Chares and Entry points.
4 */
5 #ifndef _REGISTER_H
6 #define _REGISTER_H
7 /** \addtogroup CkRegister */
8 /*@{*/
10 /**
11 Represents a single entry method or constructor.
12 EntryInfo's are always stored in the _entryTable, and can
13 be referred to across processors by their index into the
14 _entryTable--this is the entry point's index, often abbreviated
15 "epIdx".
17 Although this class is always created via a clean, well-defined
18 API (the CkRegister* routines in charm.h); access to these classes
19 is completely direct-- the ck.C routines just access, e.g.,
20 _entryTable[epIdx]->chareIdx.
22 class EntryInfo {
23 public:
24 /// Human-readable name of entry method, including parameters.
25 const char *name;
27 /**
28 A "call function" is how Charm++ actually invokes an
29 entry method on an object. Call functions take two parameters:
30 1.) The message to pass to the method. This may be
31 a regular message, a CkMarshallMsg for a
32 parameter-marshalled method, or a "SysMsg" for a void method.
33 For migration constructors, the "message" might
34 even be NULL.
35 2.) The object to invoke the method on.
36 Call functions are always generated by the translator.
38 A simple call function to invoke a method foo::bar(fooMsg *)
39 might look like this:
40 <pre>
41 extern "C" void __call_foo_bar(void *msg,void *obj) {
42 fooMsg *m=(fooMsg *)msg;
43 foo *f=(foo *)obj;
44 f->bar(m);
46 </pre>
47 Call functions are even used to invoke constructors on new
48 Chares.
50 CkCallFnPtr call;
51 /// Our parameters' index into the _msgTable
52 int msgIdx;
53 /// Our chare's index into the _chareTable
54 int chareIdx;
55 /// Charm++ Tracing enabled for this ep (can change dynamically)
56 bool traceEnabled;
57 /// Method doesn't keep (and delete) message passed in to it.
58 bool noKeep;
59 /// true if this EP is charm internal functions
60 bool inCharm;
61 bool appWork;
62 #ifdef ADAPT_SCHED_MEM
63 /// true if this EP is used to be rescheduled when adjusting memory usage
64 bool isMemCritical;
65 #endif
66 /**
67 A "marshall unpack" function:
68 1.) Pups method parameters out of the buffer passed in to it.
69 2.) Calls a method on the object passed in.
70 3.) Returns the number of bytes of the buffer consumed.
71 It can be used for very efficient delivery of
72 a whole set of combined messages.
74 CkMarshallUnpackFn marshallUnpack;
76 #if CMK_CHARMDEBUG
77 /**
78 A "message pup" function pups the message accepted by
79 this entry point. This is *only* used to display the
80 message in the debugger, not for normal communication.
82 This is registered with the entry point
83 (not the message) because many entry points take the same
84 message type but store different data in it, like parameter
85 marshalled messages.
87 CkMessagePupFn messagePup;
88 #endif
90 EntryInfo(const char *n, CkCallFnPtr c, int m, int ci) :
91 name(n), call(c), msgIdx(m), chareIdx(ci),
92 marshallUnpack(0)
93 #if CMK_CHARMDEBUG
94 , messagePup(0)
95 #endif
96 { traceEnabled=true; noKeep=false; inCharm=false; appWork=false;}
99 /**
100 Represents one type of Message.
101 It is always stored in _msgTable.
103 class MsgInfo {
104 public:
105 /// Human-readable name of message, like "CkMarshallMsg".
106 const char *name;
108 A message pack function converts the (possibly complex)
109 message into a flat array of bytes. This method is called
110 whenever messages are sent or duplicated, so for speed
111 messages normally have a layout which allows this conversion
112 to be done in-place, typically by just moving some pointers
113 around in the message.
115 There was once a time when the pack function could be NULL,
116 meaning the message can be sent without packing, but today
117 the pack function is always set. Note: pack and unpack have
118 nothing to do with the PUP framework.
120 CkPackFnPtr pack;
122 A message unpack function converts a flat array of bytes into
123 a living message. It's just the opposite of pack.
125 CkUnpackFnPtr unpack;
127 A message deallocation function deletes the message with the
128 appropriate actions.
130 CkDeallocFnPtr dealloc;
132 This message body's allocation size. This does *not* include
133 any dynamically allocated portion of the message, so is a lower
134 bound on the message size.
136 size_t size;
138 MsgInfo(const char *n,CkPackFnPtr p,CkUnpackFnPtr u,CkDeallocFnPtr d,int s):
139 name(n), pack(p), unpack(u), dealloc(d), size(s)
144 Represents a class of Chares (or array or group elements).
145 It is always stored in the _chareTable.
147 class ChareInfo {
148 public:
149 /// Human-readable name of the chare class, like "MyFoo".
150 const char *name;
151 /// Size, in bytes, of the body of the chare.
152 int size;
154 /// Constructor epIdx: default constructor and migration constructor (or -1 if none).
155 int defCtor,migCtor;
156 /// Number of base classes:
157 int numbases;
158 /// chareIdx of each base class.
159 int bases[16];
161 /// For groups -- 1 if the group is Irreducible
162 int isIrr;
164 /// chare type
165 ChareType chareType;
167 /// true if this EP is charm internal functions
168 bool inCharm;
170 int mainChareIdx;
172 ChareInfo(const char *n, int s, ChareType t) : name(n), size(s) {
173 defCtor=migCtor=-1;
174 isIrr = numbases = 0;
175 chareType = t;
176 inCharm = false;
177 mainChareIdx = -1;
179 void setDefaultCtor(int idx) { defCtor = idx; }
180 int getDefaultCtor(void) { return defCtor; }
181 void setMigCtor(int idx) { migCtor = idx; }
182 int getMigCtor(void) { return migCtor; }
183 void addBase(int idx) { bases[numbases++] = idx; }
184 void setInCharm() { inCharm = true; }
185 bool isInCharm() { return inCharm; }
186 void setMainChareType(int idx) { mainChareIdx = idx; }
187 int mainChareType() { return mainChareIdx; }
190 /// Describes a mainchare's constructor. These are all executed at startup.
191 class MainInfo {
192 public:
193 const char *name;
194 int chareIdx;
195 int entryIdx;
196 int entryMigCtor;
197 void* obj; // real type is Chare*
198 MainInfo(int c, int e) : name("main"), chareIdx(c), entryIdx(e) {}
199 inline void* getObj(void) { return obj; }
200 inline void setObj(void *_obj) { obj=_obj; }
203 /// Describes a readonly global variable.
204 class ReadonlyInfo {
205 public:
206 /// Human-readable string name of variable (e.g., "nElements") and type (e.g., "int").
207 const char *name,*type;
208 /// Size in bytes of basic value.
209 int size;
210 /// Address of basic value.
211 void *ptr;
212 /// Pup routine for value, or NULL if no pup available.
213 CkPupReadonlyFnPtr pup;
215 /// Pup this global variable.
216 void pupData(PUP::er &p) {
217 if (pup!=NULL)
218 (pup)((void *)&p);
219 else
220 p((char *)ptr,size);
222 ReadonlyInfo(const char *n,const char *t,
223 int s, void *p,CkPupReadonlyFnPtr pf)
224 : name(n), type(t), size(s), ptr(p), pup(pf) {}
228 Describes a readonly message. Readonly messages were
229 once the only way to get a truly variable-sized readonly,
230 but now that readonlies are pup'd they are almost totally useless.
232 class ReadonlyMsgInfo {
233 public:
234 const char *name, *type;
235 void **pMsg;
236 ReadonlyMsgInfo(const char *n, const char *t,
237 void **p) : name(n), type(t), pMsg(p) {}
241 This class stores registered entities, like EntryInfo's,
242 in a linear list indexed by index ("idx").
244 template <class T>
245 class CkRegisteredInfo {
246 CkVec<T *> vec;
248 void outOfBounds(int idx) {
249 const char *exampleName="";
250 if (vec.size()>0) exampleName=vec[0]->name;
251 CkPrintf("register.h> CkRegisteredInfo<%d,%s> called with invalid index "
252 "%d (should be less than %d)\n", sizeof(T),exampleName,
253 idx, vec.size());
254 CkAbort("Registered idx is out of bounds-- is message or memory corrupted?");
256 public:
258 Subtle: we *don't* want to call vec's constructor,
259 because the order in which constructors for global
260 variables get called is undefined.
261 Hence we rely on the implicit zero-initialization
262 that all globals get.
264 CkRegisteredInfo() :vec(CkSkipInitialization()) {}
265 ~CkRegisteredInfo() {
266 for (size_t i=0; i<vec.size(); i++) if (vec[i]) delete vec[i];
269 /// Add a heap-allocated registration record,
270 /// returning the index used.
271 int add(T *t) {
272 #if CMK_ERROR_CHECKING
273 /* Make sure registrations only happen from rank 0: */
274 if (CkMyRank()!=0)
275 CkAbort("Can only do registrations from rank 0 processors");
276 #endif
277 vec.push_back(t);
278 return vec.size()-1;
281 /// Return the number of registered entities in this table.
282 /// (This is a reference so the CpdLists can stay up to date).
283 size_t &size(void) {return vec.length();}
285 /// Return the registered data at this index.
286 T *operator[](size_t idx) {
287 #if CMK_ERROR_CHECKING
288 /* Bounds-check the index: */
289 if (idx>=vec.size()) outOfBounds(idx);
290 #endif
291 return vec[idx];
295 /// These tables are shared between all processors on a node.
296 extern CkRegisteredInfo<EntryInfo> _entryTable;
297 extern CkRegisteredInfo<MsgInfo> _msgTable;
298 extern CkRegisteredInfo<ChareInfo> _chareTable;
299 extern CkRegisteredInfo<MainInfo> _mainTable;
300 extern CkRegisteredInfo<ReadonlyInfo> _readonlyTable;
301 extern CkRegisteredInfo<ReadonlyMsgInfo> _readonlyMsgs;
303 extern void _registerInit(void);
304 extern void _registerDone(void);
306 /*@}*/
307 #endif