bugfix: provide html.sty and symlink to fix markup
[charm.git] / src / ck-core / ck.h
blobaa22e4aafd366ef98b9999a175f6054a74c9a1d5
1 #ifndef _CK_H_
2 #define _CK_H_
4 #include <string.h>
5 #include <stdlib.h>
6 #include <math.h>
7 #include "qd.h"
8 #include "charm++.h"
9 #include "envelope.h"
10 #include "register.h"
11 #include "stats.h"
12 #include "ckfutures.h"
13 #include "TopoManager.h"
15 #if CMK_ERROR_CHECKING
16 #define _CHECK_VALID(p, msg) do {if((p)==0){CkAbort(msg);}} while(0)
17 #else
18 #define _CHECK_VALID(p, msg) do { } while(0)
19 #endif
21 // Flag that tells the system if we are replaying using Record/Replay
22 CMI_EXTERNC_VARIABLE int _replaySystem;
24 #if CMK_CHARMDEBUG
25 extern "C" int ConverseDeliver(int pe);
26 inline void _CldEnqueue(int pe, void *msg, int infofn) {
27 if (!ConverseDeliver(pe)) {
28 CmiFree(msg);
29 return;
31 #if CMK_ONESIDED_IMPL
32 if(((envelope *)msg)->isRdma()){
33 CkRdmaPrepareMsg((envelope **)&msg, pe);
35 #endif
36 CldEnqueue(pe, msg, infofn);
38 inline void _CldEnqueueMulti(int npes, int *pes, void *msg, int infofn) {
39 if (!ConverseDeliver(-1)) {
40 CmiFree(msg);
41 return;
43 CldEnqueueMulti(npes, pes, msg, infofn);
45 inline void _CldEnqueueGroup(CmiGroup grp, void *msg, int infofn) {
46 if (!ConverseDeliver(-1)) {
47 CmiFree(msg);
48 return;
50 CldEnqueueGroup(grp, msg, infofn);
52 inline void _CldNodeEnqueue(int node, void *msg, int infofn) {
53 if (!ConverseDeliver(node)) {
54 CmiFree(msg);
55 return;
57 #if CMK_ONESIDED_IMPL
58 if(((envelope *)msg)->isRdma()){
59 CkRdmaPrepareMsg((envelope **)&msg, CmiNodeFirst(node));
61 #endif
62 CldNodeEnqueue(node, msg, infofn);
64 #else
66 inline void _CldEnqueue(int pe, void *msg, int infofn) {
67 #if CMK_ONESIDED_IMPL
68 if(((envelope *)msg)->isRdma()){
69 CkRdmaPrepareMsg((envelope **)&msg, pe);
71 #endif
72 CldEnqueue(pe, msg, infofn);
75 inline void _CldNodeEnqueue(int node, void *msg, int infofn) {
76 #if CMK_ONESIDED_IMPL
77 if(((envelope *)msg)->isRdma()){
78 CkRdmaPrepareMsg((envelope **)&msg, CmiNodeFirst(node));
80 #endif
81 CldNodeEnqueue(node, msg, infofn);
83 #define _CldEnqueueMulti CldEnqueueMulti
84 #define _CldEnqueueGroup CldEnqueueGroup
85 #endif
87 #ifndef CMK_CHARE_USE_PTR
88 CkpvExtern(std::vector<void *>, chare_objs);
89 #endif
91 #include <unordered_map>
92 typedef std::unordered_map<CmiUInt8, ArrayElement*> ArrayObjMap;
93 CkpvExtern(ArrayObjMap, array_objs);
95 /// A set of "Virtual ChareID"'s
96 class VidBlock {
97 enum VidState : uint8_t {FILLED, UNFILLED};
98 VidState state;
99 PtrQ *msgQ;
100 CkChareID actualID;
101 void msgDeliver(envelope *env) {
102 // This was causing sync entry methods not to return properly in some cases
103 //env->setSrcPe(CkMyPe());
104 env->setMsgtype(ForChareMsg);
105 env->setObjPtr(actualID.objPtr);
106 _CldEnqueue(actualID.onPE, env, _infoIdx);
107 CpvAccess(_qd)->create();
109 public:
110 VidBlock() ;
111 void send(envelope *env) {
112 if(state==UNFILLED) {
113 msgQ->enq((void *)env);
114 } else {
115 msgDeliver(env);
118 void fill(int onPE, void *oPtr) {
119 state = FILLED;
120 actualID.onPE = onPE;
121 actualID.objPtr = oPtr;
122 envelope *env;
123 while(NULL!=(env=(envelope*)msgQ->deq())) {
124 msgDeliver(env);
126 delete msgQ; msgQ=0;
128 void *getLocalChare(void) {
129 if (state==FILLED && actualID.onPE==CkMyPe())
130 return actualID.objPtr;
131 return NULL;
133 void *getLocalChareObj(void) {
134 // returns actual object, different when CMK_CHARE_USE_PTR is false
135 if (state==FILLED && actualID.onPE==CkMyPe())
136 #ifdef CMK_CHARE_USE_PTR
137 return actualID.objPtr;
138 #else
139 return CkpvAccess(chare_objs)[(CmiIntPtr)actualID.objPtr];
140 #endif
141 return NULL;
143 void pup(PUP::er &p) {
144 #ifndef CMK_CHARE_USE_PTR
145 int s = 0;
146 if (!p.isUnpacking()) s = state-FILLED;
147 p|s;
148 if (p.isUnpacking()) state = (VidState)(FILLED+s);
149 if (p.isUnpacking()) msgQ = NULL; // fixme
150 p|actualID;
151 #endif
155 class CkCoreState;
157 /// Message watcher: for record/replay support
158 class CkMessageWatcher {
159 protected:
160 FILE *f;
161 CkMessageWatcher *next;
162 public:
163 CkMessageWatcher() : f(NULL), next(NULL) { }
164 virtual ~CkMessageWatcher();
166 * This message is about to be processed by Charm.
167 * If this function returns false, the message will not be processed.
168 * The message is processed by the watcher starting from the innermost one
169 * up to the outermost
171 #define PROCESS_MACRO(name,type) inline bool process##name(type *input,CkCoreState *ck) { \
172 bool result = true; \
173 if (next != NULL) result &= next->process##name(input, ck); \
174 result &= process(input, ck); \
175 return result; \
178 PROCESS_MACRO(Message,envelope*);
179 PROCESS_MACRO(Thread,CthThreadToken);
180 PROCESS_MACRO(LBMessage,LBMigrateMsg*);
182 #undef PROCESS_MACRO
183 protected:
184 /** These are used internally by this class to call the correct subclass method */
185 virtual bool process(envelope **env,CkCoreState *ck) =0;
186 virtual bool process(CthThreadToken *token, CkCoreState *ck) {return true;}
187 virtual bool process(LBMigrateMsg **msg, CkCoreState *ck) {return true;}
188 public:
189 inline void setNext(CkMessageWatcher *w) { next = w; }
192 /// All the state that's useful to have on the receive side in the Charm Core (ck.C)
193 class CkCoreState {
194 GroupTable *groupTable;
195 QdState *qd;
196 public:
197 CkMessageWatcher *watcher;
198 /** Adds an extra watcher (which wrap the previously existing one) */
199 inline void addWatcher(CkMessageWatcher *w) {
200 w->setNext(watcher);
201 watcher = w;
204 CkCoreState()
205 :groupTable(CkpvAccess(_groupTable)),
206 qd(CpvAccess(_qd)) { watcher=NULL; }
207 ~CkCoreState() { delete watcher;}
209 inline GroupTable *getGroupTable() const {
210 return groupTable;
212 inline IrrGroup *localBranch(CkGroupID gID) const {
213 return groupTable->find(gID).getObj();
216 inline QdState *getQD() {return qd;}
217 // when in interrupt based net version, use the extra copy
218 // of qd when inside an immediate handler function.
219 inline void process(int n=1) {
220 if (CmiImmIsRunning())
221 CpvAccessOther(_qd, 1)->process(n);
222 else
223 qd->process(n);
225 inline void create(int n=1) {
226 if (CmiImmIsRunning())
227 CpvAccessOther(_qd, 1)->create(n);
228 else
229 qd->create(n);
233 CkpvExtern(CkCoreState *, _coreState);
235 void CpdHandleLBMessage(LBMigrateMsg **msg);
236 void CkMessageWatcherInit(char **argv,CkCoreState *ck);
238 extern void _processHandler(void *converseMsg,CkCoreState *ck);
239 extern void _processBocInitMsg(CkCoreState *ck,envelope *msg);
240 extern void _processNodeBocInitMsg(CkCoreState *ck,envelope *msg);
241 extern void _infoFn(void *msg, CldPackFn *pfn, int *len,
242 int *queueing, int *priobits, UInt **prioptr);
243 extern void CkCreateLocalGroup(CkGroupID groupID, int eIdx, envelope *env);
244 extern void CkCreateLocalNodeGroup(CkGroupID groupID, int eIdx, envelope *env);
245 extern void _createGroup(CkGroupID groupID, envelope *env);
246 extern void _createNodeGroup(CkGroupID groupID, envelope *env);
247 extern int _getGroupIdx(int,int,int);
248 static inline IrrGroup *_lookupGroupAndBufferIfNotThere(const CkCoreState *ck, const envelope *env,const CkGroupID &groupID);
251 void QdCreate(int n);
252 void QdProcess(int n);
253 #endif