updated CUDA hybridAPI and added a CUDA hello example
[charm.git] / src / conv-core / converse.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$ 
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**
9   Main Converse header file.  Everything in Converse is 
10   either declared here directly, or else included from here.
11
12   Routine names in Converse include a short prefix starting with "C".
13   These generally tell you what category the routine is in:
14   - Cmi, Converse Machine Interface, the machine layer. (machine.c)
15      Also used for various generic low-level features.
16   - Cth, Converse threads, user-level nonpreemptive threads. (threads.c) 
17   - Ccd, Converse condition detection, similar to signal handling. (conv-conds.c)
18   - Ccs, Converse client/server, socket access to parallel job. (conv-ccs.c; ccs-*)
19   - Cpd, Converse parallel debugger. (debug-*)
20   - Crn, Converse random number generation. (random.c)
21   - Csd, Converse scheduler daemon.  (convcore.c)
22   - Cqs, Converse prioritized queueing system. (queueing.c)
23   - CQd, Converse quiesence detection. (quiescense.c)
24      Not the same as Charm++ QD. (qd.C)
25   
26   Globally accessible variables in Converse can be shared as:
27   - Cpv, Converse processor-private variable.  Very common;
28      one copy per processor of each node.
29   - Ctv, Converse thread-private variable.  One copy per Converse thread. 
30   - Csv, Converse node-shared variable.  Global variables 
31      shared by all processors of a node (beware of thread safety!)
32 */
33 #ifndef CONVERSE_H
34 #define CONVERSE_H
35
36 #define ALIGN8(x)        (int)((~7)&((x)+7))
37
38 /**
39   Grab configuration files generated by build and configure scripts. 
40 */
41 #include "conv-config.h"
42
43 #if CMK_HAS_STDINT_H
44 #include <stdint.h>
45 #endif
46
47 #include <stdlib.h>
48
49 /* Paste the tokens x and y together, without any space between them.
50    The ANSI C way to do this is the bizarre ## "token-pasting" 
51    preprocessor operator.
52  */
53 #define CMK_CONCAT(x,y) x##y
54 /* Tag variable y as being from unit x: */
55 #define CMK_TAG(x,y) x##y##_
56
57
58 #include "pup_c.h"
59
60 /* the following flags denote properties of the C compiler,  */
61 /* not the C++ compiler.  If this is C++, ignore them.       */
62 #ifdef __cplusplus
63
64 /* Only C++ needs this backup bool defined.  We'll assume that C doesn't
65    use it */
66
67 #if ! CMK_BOOL_DEFINED
68 enum CmiBool {CmiFalse=0, CmiTrue=1};
69 typedef enum {false = 0, true = 1} bool;
70 #else
71 typedef bool CmiBool;
72 #define CmiFalse false
73 #define CmiTrue true
74 #endif
75
76 extern "C" {
77 #endif
78
79 /* Global variables used by charmdebug to maintain information */
80 #ifndef CMK_OPTIMIZE
81 extern int memory_status_info;
82 extern int memory_chare_id;
83 #define setMemoryStatus(p) { \
84   int tmp = memory_status_info; \
85   memory_status_info = p; \
86   p = tmp; \
87 }
88 int setMemoryChareIDFromPtr(void *p);
89 void setMemoryChareID(int id);
90 #else
91 #define setMemoryStatus(p) /* empty */
92 #define setMemoryChareIDFromPtr(p) /* empty */
93 #define setMemoryChareID(p) /* empty */
94 #endif
95
96 /******************************************************************************
97  *
98  * Deal with Shared Memory
99  *
100  * Shared memory strongly affects how CPV, CSV, and CmiMyPe are defined,
101  * and how memory locking is performed. Therefore, we control all these
102  * functions with a single flag.
103  *
104  *****************************************************************************/
105
106 #ifdef __cplusplus
107 /* In C++, use new so t's constructor gets called */
108 # define CpvInit_Alloc(t,n) new t[n]
109 # define CpvInit_Alloc_scalar(t) new t
110 #else
111 # define CpvInit_Alloc(t,n) (t *)calloc(n,sizeof(t))
112 # define CpvInit_Alloc_scalar(t) (t *)calloc(1,sizeof(t))
113 #endif
114
115 #if CMK_SHARED_VARS_UNAVAILABLE /* Non-SMP version of shared vars. */
116 extern int _Cmi_mype;
117 extern int _Cmi_numpes;
118 extern int _Cmi_myrank; /* Normally zero; only 1 during SIGIO handling */
119
120 #define CmiMyPe()           _Cmi_mype
121 #define CmiMyRank()         0
122 #define CmiNumPes()         _Cmi_numpes
123 #define CmiMyNodeSize()     1
124 #define CmiMyNode()         _Cmi_mype
125 #define CmiNumNodes()       _Cmi_numpes
126 #define CmiNodeFirst(node)  (node)
127 #define CmiNodeSize(node)   1
128 #define CmiNodeOf(pe)       (pe)
129 #define CmiRankOf(pe)       0
130
131 #define CpvDeclare(t,v) t CMK_TAG(Cpv_,v)[2]
132 #define CpvExtern(t,v)  extern t CMK_TAG(Cpv_,v)[2]
133 #ifdef __cplusplus
134 #define CpvCExtern(t,v)    extern "C" t CMK_TAG(Cpv_,v)[2]
135 #else
136 #define CpvCExtern(t,v)    CpvExtern(t,v)
137 #endif
138 #define CpvStaticDeclare(t,v) static t CMK_TAG(Cpv_,v)[2]
139 #define CpvInitialize(t,v) do {} while(0)
140 #define CpvInitialized(v) 1
141 #define CpvAccess(v) CMK_TAG(Cpv_,v)[_Cmi_myrank]
142 #define CpvAccessOther(v, r) CMK_TAG(Cpv_,v)[r]
143
144 extern void CmiMemLock();
145 extern void CmiMemUnlock();
146 #define CmiNodeBarrier() /*empty*/
147 #define CmiNodeAllBarrier() /*empty*/
148 #define CmiSvAlloc CmiAlloc
149
150 typedef int CmiNodeLock;
151 #define CmiCreateLock() (0)
152 #define CmiLock(lock) {(lock)++;}
153 #define CmiUnlock(lock)  {(lock)--;}
154 #define CmiTryLock(lock)  ((lock)?1:((lock)=1,0))
155 #define CmiDestroyLock(lock) /*empty*/
156
157 #endif
158
159 #if CMK_SHARED_VARS_POSIX_THREADS_SMP /*Used by the net-*-smp versions*/
160
161 #include <pthread.h>
162 #include <sched.h>
163 #ifdef CMK_FAKE_SCHED_YIELD
164 #include <unistd.h>
165 #define sched_yield() sleep(0)
166 #endif
167
168 extern int _Cmi_numpes;
169 extern int _Cmi_mynodesize;
170 extern int _Cmi_mynode;
171 extern int _Cmi_numnodes;
172 extern int _Cmi_noprocforcommthread;
173
174 extern int CmiMyPe();
175 extern int CmiMyRank();
176 #define CmiNumPes()         _Cmi_numpes
177 #define CmiMyNodeSize()     _Cmi_mynodesize
178 #define CmiMyNode()         _Cmi_mynode
179 #define CmiNumNodes()       _Cmi_numnodes
180 extern int CmiNodeFirst(int node);
181 extern int CmiNodeSize(int node);
182 extern int CmiNodeOf(int pe);
183 extern int CmiRankOf(int pe);
184
185 #define CMK_CPV_IS_SMP sched_yield();
186
187 extern void CmiNodeBarrier(void);
188 extern void CmiNodeAllBarrier(void);
189 #define CmiSvAlloc CmiAlloc
190
191 typedef pthread_mutex_t *CmiNodeLock;
192 extern CmiNodeLock CmiCreateLock();
193 #define CmiLock(lock) (pthread_mutex_lock(lock))
194 #define CmiUnlock(lock) (pthread_mutex_unlock(lock))
195 #define CmiTryLock(lock) (pthread_mutex_trylock(lock))
196 extern void CmiDestroyLock(CmiNodeLock lock);
197
198 extern CmiNodeLock CmiMemLock_lock;
199 #define CmiMemLock() do{if (CmiMemLock_lock) CmiLock(CmiMemLock_lock);} while (0)
200
201 #define CmiMemUnlock() do{if (CmiMemLock_lock) CmiUnlock(CmiMemLock_lock);} while (0)
202
203
204 #endif
205
206 #include "string.h"
207
208 #if CMK_VERSION_BLUEGENE || CMK_BLUEGENEP
209 #include "cmimemcpy.h"
210 #else
211 #define CmiMemcpy(dest, src, size) memcpy((dest), (src), (size))
212 #endif
213
214 #if CMK_SHARED_VARS_EXEMPLAR /* Used only by HP Exemplar version */
215
216 #include <spp_prog_model.h>
217 #include <cps.h>
218
219 extern int _Cmi_numpes;
220 extern int _Cmi_mynodesize;
221
222 #define CmiMyPe()           (my_thread())
223 #define CmiMyRank()         (my_thread())
224 #define CmiNumPes()         _Cmi_numpes
225 #define CmiMyNodeSize()     _Cmi_numpes
226 #define CmiMyNode()         0
227 #define CmiNumNodes()       1
228 #define CmiNodeFirst(node)  0
229 #define CmiNodeSize(node)   _Cmi_numpes
230 #define CmiNodeOf(pe)       0
231 #define CmiRankOf(pe)       (pe)
232
233 #define CMK_CPV_IS_SMP {} 
234
235 extern void CmiMemLock();
236 extern void CmiMemUnlock();
237 extern void CmiNodeBarrier(void);
238 extern void *CmiSvAlloc(int);
239
240 typedef cps_mutex_t *CmiNodeLock;
241 extern CmiNodeLock CmiCreateLock(void);
242 #define CmiLock(lock) (cps_mutex_lock(lock))
243 #define CmiUnlock(lock) (cps_mutex_unlock(lock))
244 #define CmiTryLock(lock) (cps_mutex_trylock(lock))
245 #define CmiDestroyLock(lock) (cps_mutex_free(lock))
246
247 #endif
248
249 #if CMK_SHARED_VARS_UNIPROCESSOR /*Used only by uth- and sim- versions*/
250
251 extern int _Cmi_mype;
252 extern int _Cmi_numpes;
253
254 #define CmiMyPe()              _Cmi_mype
255 #define CmiMyRank()            _Cmi_mype
256 #define CmiNumPes()            _Cmi_numpes
257 #define CmiMyNodeSize()        _Cmi_numpes
258 #define CmiMyNode()            0
259 #define CmiNumNodes()          1
260 #define CmiNodeFirst(node)     0
261 #define CmiNodeSize(node)      _Cmi_numpes
262 #define CmiNodeOf(pe)          0
263 #define CmiRankOf(pe)          (pe)
264
265 #define CpvDeclare(t,v) t* CMK_TAG(Cpv_,v)
266 #define CpvExtern(t,v)  extern t* CMK_TAG(Cpv_,v)
267 #ifdef __cplusplus
268 #define CpvCExtern(t,v)  extern "C" t* CMK_TAG(Cpv_,v)
269 #else
270 #define CpvCExtern(t,v)    CpvExtern(t,v)
271 #endif
272 #define CpvStaticDeclare(t,v) static t* CMK_TAG(Cpv_,v)
273 #define CpvInitialize(t,v)\
274   do  { if (CMK_TAG(Cpv_,v)==0)\
275         { CMK_TAG(Cpv_,v) = CpvInit_Alloc(t,CmiNumPes()); }}\
276   while(0)
277 #define CpvInitialized(v) (0!=CMK_TAG(Cpv_,v))
278 #define CpvAccess(v) CMK_TAG(Cpv_,v)[CmiMyPe()]
279 #define CpvAccessOther(v, r) CMK_TAG(Cpv_,v)[r]
280
281 #define CmiMemLock() 0
282 #define CmiMemUnlock() 0
283 extern void CmiNodeBarrier();
284 extern void CmiNodeAllBarrier();
285 #define CmiSvAlloc CmiAlloc
286
287 typedef int *CmiNodeLock;
288 extern CmiNodeLock  CmiCreateLock(void);
289 extern void         CmiLock(CmiNodeLock lock);
290 extern void         CmiUnlock(CmiNodeLock lock);
291 extern int          CmiTryLock(CmiNodeLock lock);
292 extern void         CmiDestroyLock(CmiNodeLock lock);
293
294 #endif
295
296 #if CMK_SHARED_VARS_PTHREADS /*Used only by origin-pthreads*/
297
298 #include <pthread.h>
299 #include <sched.h>
300
301 extern int CmiMyPe();
302 extern int _Cmi_numpes;
303
304 #define CmiNumPes()            _Cmi_numpes
305 #define CmiMyRank()            CmiMyPe()
306 #define CmiMyNodeSize()        _Cmi_numpes
307 #define CmiMyNode()            0
308 #define CmiNumNodes()          1
309 #define CmiNodeFirst(node)     0
310 #define CmiNodeSize(node)      _Cmi_numpes
311 #define CmiNodeOf(pe)          0
312 #define CmiRankOf(pe)          (pe)
313
314 #define CMK_CPV_IS_SMP sched_yield();
315
316 extern void CmiMemLock();
317 extern void CmiMemUnlock();
318 extern void CmiNodeBarrier();
319 extern void CmiNodeAllBarrier();
320 #define CmiSvAlloc CmiAlloc
321
322 typedef pthread_mutex_t *CmiNodeLock;
323 extern CmiNodeLock  CmiCreateLock(void);
324 extern void         CmiLock(CmiNodeLock lock);
325 extern void         CmiUnlock(CmiNodeLock lock);
326 extern int          CmiTryLock(CmiNodeLock lock);
327 extern void         CmiDestroyLock(CmiNodeLock lock);
328
329 #endif
330
331 #if CMK_SHARED_VARS_NT_THREADS /*Used only by win32 versions*/
332
333 #include <windows.h>
334
335 extern int _Cmi_numpes;
336 extern int _Cmi_mynodesize;
337 extern int _Cmi_mynode;
338 extern int _Cmi_numnodes;
339 extern int _Cmi_noprocforcommthread;
340
341 extern int CmiMyPe();
342 extern int CmiMyRank();
343 #define CmiNumPes()         _Cmi_numpes
344 #define CmiMyNodeSize()     _Cmi_mynodesize
345 #define CmiMyNode()         _Cmi_mynode
346 #define CmiNumNodes()       _Cmi_numnodes
347 extern int CmiNodeFirst(int node);
348 extern int CmiNodeSize(int node);
349 extern int CmiNodeOf(int pe);
350 extern int CmiRankOf(int pe);
351
352 #define CMK_CPV_IS_SMP Sleep(0);
353
354 extern void CmiNodeBarrier(void);
355 extern void CmiNodeAllBarrier(void);
356 #define CmiSvAlloc CmiAlloc
357
358 typedef HANDLE CmiNodeLock;
359 extern  CmiNodeLock CmiCreateLock(void);
360 #define CmiLock(lock) (WaitForSingleObject(lock, INFINITE))
361 #define CmiUnlock(lock) (ReleaseMutex(lock))
362 #define CmiTryLock(lock) (WaitForSingleObject(lock, 0))
363 extern  void CmiDestroyLock(CmiNodeLock lock);
364
365 extern CmiNodeLock CmiMemLock_lock;
366 #define CmiMemLock() do{if (CmiMemLock_lock) CmiLock(CmiMemLock_lock);} while (0)
367 #define CmiMemUnlock() do{if (CmiMemLock_lock) CmiUnlock(CmiMemLock_lock);} while (0)
368
369 #endif
370
371 #if CMK_SHARED_VARS_UNAVAILABLE   /* non-SMP version */
372
373 typedef int CmiImmediateLockType;
374 extern int _immediateLock;
375 extern int _immediateFlag;
376 #define CmiCreateImmediateLock() (0)
377 #define CmiImmediateLock(ignored) { _immediateLock++; }
378 #if CMK_IMMEDIATE_MSG
379 #define CmiImmediateUnlock(ignored) \
380   { _immediateLock--; \
381     if(_immediateFlag) \
382       CmiProbeImmediateMsg(); } 
383 #else
384 #define CmiImmediateUnlock(ignored) { _immediateLock--; }
385 #endif
386 #define CmiCheckImmediateLock(ignored) \
387   ((_immediateLock)?((_immediateFlag=1),1):0)
388 #define CmiClearImmediateFlag() { _immediateFlag=0; }
389
390 #else /* SMP and all other weird versions */
391
392 typedef CmiNodeLock CmiImmediateLockType;
393 #define CmiCreateImmediateLock() CmiCreateLock()
394 #define CmiImmediateLock(immediateLock) CmiLock((immediateLock))
395 #define CmiImmediateUnlock(immediateLock) CmiUnlock((immediateLock)) 
396 #define CmiCheckImmediateLock(ignored)  (0)
397 #define CmiClearImmediateFlag() 
398
399 #endif
400
401 /* This is the default Cpv implmentation for SMP-style systems:
402 A Cpv variable is actually a pointer to an array of values, one
403 for each processor in the node.
404 */
405 #ifdef CMK_CPV_IS_SMP
406
407 #if CMK_TLS_THREAD && CMK_USE_TLS_THREAD
408 #define CpvDeclare(t,v) __thread t* CMK_TAG(Cpv_,v) = NULL;   \
409                         int CMK_TAG(Cpv_inited_,v) = 0;  \
410                         t * CMK_TAG(Cpv_addr_,v)[32] = {0}
411 #define CpvExtern(t,v)  extern __thread t* CMK_TAG(Cpv_,v);  \
412                         extern int CMK_TAG(Cpv_inited_,v);  \
413                         extern t * CMK_TAG(Cpv_addr_,v)[32]
414 #ifdef __cplusplus
415 #define CpvCExtern(t,v) extern "C"  __thread t* CMK_TAG(Cpv_,v);  \
416                         extern "C" int CMK_TAG(Cpv_inited_,v);  \
417                         extern "C" t * CMK_TAG(Cpv_addr_,v)[32]
418 #else
419 #define CpvCExtern(t,v)    CpvExtern(t,v)
420 #endif
421 #define CpvStaticDeclare(t,v) static __thread t* CMK_TAG(Cpv_,v);   \
422                         static int CMK_TAG(Cpv_inited_,v) = 0;  \
423                         static t * CMK_TAG(Cpv_addr_,v)[32] = {0}
424 #define CpvInitialize(t,v)\
425     do { \
426        if (CmiMyRank()) { \
427                 while (!CpvInitialized(v)) CMK_CPV_IS_SMP; \
428        } else { \
429                CMK_TAG(Cpv_inited_,v)=1; \
430        } \
431     } while(0); \
432     CMK_TAG(Cpv_,v)=CpvInit_Alloc_scalar(t);\
433     CMK_TAG(Cpv_addr_,v)[CmiMyRank()] = CMK_TAG(Cpv_,v) 
434 #define CpvInitialized(v) (0!=CMK_TAG(Cpv_inited_,v))
435 #define CpvAccess(v) (*CMK_TAG(Cpv_,v))
436 #define CpvAccessOther(v, r) (*(CMK_TAG(Cpv_addr_,v)[r]))
437
438 #else
439
440 #define CpvDeclare(t,v) t* CMK_TAG(Cpv_,v)
441 #define CpvExtern(t,v)  extern t* CMK_TAG(Cpv_,v)
442 #ifdef __cplusplus
443 #define CpvCExtern(t,v)    extern "C" t* CMK_TAG(Cpv_,v)
444 #else
445 #define CpvCExtern(t,v)    CpvExtern(t,v)
446 #endif
447 #define CpvStaticDeclare(t,v) static t* CMK_TAG(Cpv_,v)
448 #define CpvInitialize(t,v)\
449     do { \
450        if (CmiMyRank()) { \
451                 while (!CpvInitialized(v)) CMK_CPV_IS_SMP \
452        } else { \
453                CMK_TAG(Cpv_,v)=CpvInit_Alloc(t,1+CmiMyNodeSize());\
454        } \
455     } while(0)
456 #define CpvInitialized(v) (0!=CMK_TAG(Cpv_,v))
457 #define CpvAccess(v) CMK_TAG(Cpv_,v)[CmiMyRank()]
458 #define CpvAccessOther(v, r) CMK_TAG(Cpv_,v)[r]
459 #endif
460
461 #endif
462
463 /*Csv are the same almost everywhere:*/
464 #ifndef CsvDeclare
465 #define CsvDeclare(t,v) t CMK_TAG(Csv_,v)
466 #define CsvStaticDeclare(t,v) static t CMK_TAG(Csv_,v)
467 #define CsvExtern(t,v) extern t CMK_TAG(Csv_,v)
468 #define CsvInitialize(t,v) do{}while(0)
469 #define CsvAccess(v) CMK_TAG(Csv_,v)
470 #endif
471
472 extern CmiNodeLock smp_mutex;
473
474 extern int CmiBarrier(void);
475 extern int CmiBarrierZero(void);
476
477 /** Return 1 if our outgoing message queue 
478    for this node is longer than this many bytes. */
479 int CmiLongSendQueue(int forNode,int longerThanBytes);
480
481 /******** CMI: TYPE DEFINITIONS ********/
482
483 typedef CMK_TYPEDEF_INT2      CmiInt2;
484 typedef CMK_TYPEDEF_INT4      CmiInt4;
485 typedef CMK_TYPEDEF_INT8      CmiInt8;
486 typedef CMK_TYPEDEF_UINT2     CmiUInt2;
487 typedef CMK_TYPEDEF_UINT4     CmiUInt4;
488 typedef CMK_TYPEDEF_UINT8     CmiUInt8;
489 typedef CMK_TYPEDEF_FLOAT4    CmiFloat4;
490 typedef CMK_TYPEDEF_FLOAT8    CmiFloat8;
491
492 typedef void  *CmiCommHandle;
493 typedef void (*CmiHandler)(void *msg);
494 typedef void (*CmiHandlerEx)(void *msg,void *userPtr);
495
496 typedef struct CMK_MSG_HEADER_BASIC CmiMsgHeaderBasic;
497 typedef struct CMK_MSG_HEADER_EXT   CmiMsgHeaderExt;
498
499 #define CmiMsgHeaderSizeBytes (sizeof(CmiMsgHeaderBasic))
500 #define CmiExtHeaderSizeBytes (sizeof(CmiMsgHeaderExt))
501
502 /* all common extra fields in BigSim message header */
503 #define CMK_BLUEGENE_FIELDS  CmiInt4 nd,n; double rt; CmiInt2 tID, hID; char t, flag; CmiInt2 ref; CmiInt4 msgID, srcPe;
504
505 #ifndef CmiReservedHeaderSize
506 typedef struct CMK_MSG_HEADER_BLUEGENE   CmiBlueGeneMsgHeader;
507 #define CmiBlueGeneMsgHeaderSizeBytes (sizeof(CmiBlueGeneMsgHeader))
508 #if CMK_BLUEGENE_CHARM
509 #  define CmiReservedHeaderSize   CmiBlueGeneMsgHeaderSizeBytes
510 #else
511 #  define CmiReservedHeaderSize   CmiExtHeaderSizeBytes
512 #endif
513 #endif
514
515 /******** CMI, CSD: MANY LOW-LEVEL OPERATIONS ********/
516
517 typedef struct {
518         CmiHandlerEx hdlr;
519         void *userPtr;
520 } CmiHandlerInfo;
521
522 CpvExtern(CmiHandlerInfo*, CmiHandlerTable);
523 CpvExtern(int,         CmiHandlerMax);
524 CpvExtern(void*,       CsdSchedQueue);
525 #if CMK_GRID_QUEUE_AVAILABLE
526 CpvExtern(void *,      CsdGridQueue);
527 #endif
528 #if CMK_OBJECT_QUEUE_AVAILABLE
529 CpvExtern(void*,       CsdObjQueue);
530 #endif
531 #if CMK_NODE_QUEUE_AVAILABLE
532 CsvExtern(void*,       CsdNodeQueue);
533 CsvExtern(CmiNodeLock, CsdNodeQueueLock);
534 #endif
535 CpvExtern(int,         CsdStopFlag);
536 CpvExtern(int,         CsdLocalCount);
537 #define CSD_LOCAL_MAX_DEFAULT 0
538
539 extern int CmiRegisterHandler(CmiHandler h);
540 extern int CmiRegisterHandlerEx(CmiHandlerEx h,void *userPtr);
541 #if CMI_LOCAL_GLOBAL_AVAILABLE
542 extern int CmiRegisterHandlerLocal(CmiHandler);
543 extern int CmiRegisterHandlerGlobal(CmiHandler);
544 #endif
545 extern void CmiNumberHandler(int n, CmiHandler h);
546 extern void CmiNumberHandlerEx(int n, CmiHandlerEx h,void *userPtr);
547
548 #define CmiGetHandler(m)  (((CmiMsgHeaderExt*)m)->hdl)
549 #define CmiGetXHandler(m) (((CmiMsgHeaderExt*)m)->xhdl)
550 #define CmiGetInfo(m)     (((CmiMsgHeaderExt*)m)->info)
551
552 #define CmiSetHandler(m,v)  do {((((CmiMsgHeaderExt*)m)->hdl)=(v));} while(0)
553 #define CmiSetXHandler(m,v) do {((((CmiMsgHeaderExt*)m)->xhdl)=(v));} while(0)
554 #define CmiSetInfo(m,v)     do {((((CmiMsgHeaderExt*)m)->info)=(v));} while(0)
555
556 #define CmiHandlerToInfo(n) (CpvAccess(CmiHandlerTable)[n])
557 #define CmiHandlerToFunction(n) (CmiHandlerToInfo(n).hdlr)
558 #define CmiGetHandlerInfo(env) (CmiHandlerToInfo(CmiGetHandler(env)))
559 #define CmiGetHandlerFunction(env) (CmiHandlerToFunction(CmiGetHandler(env)))
560
561 #if CMK_MEM_CHECKPOINT
562 extern int cur_restart_phase;      /* number of restarts */
563 #undef CmiSetHandler
564 #define CmiSetHandler(m,v)  do {(((CmiMsgHeaderExt*)m)->hdl)=(v); (((CmiMsgHeaderExt*)m)->pn)=cur_restart_phase;} while(0)
565 #endif
566
567 /** This header goes before each chunk of memory allocated with CmiAlloc. 
568     See the comment in convcore.c for details on the fields.
569 */
570 typedef struct {
571   int size;
572   int ref;
573 } CmiChunkHeader;
574
575 #if CMK_USE_IBVERBS
576 struct infiCmiChunkMetaDataStruct;
577
578 typedef struct infiCmiChunkHeaderStruct{
579   struct infiCmiChunkMetaDataStruct *metaData;
580         CmiChunkHeader chunkHeader;
581 } infiCmiChunkHeader;
582
583 struct infiCmiChunkMetaDataStruct *registerMultiSendMesg(char *msg,int msgSize);
584 #endif
585
586 /* Given a user chunk m, extract the enclosing chunk header fields: */
587 #define SIZEFIELD(m) (((CmiChunkHeader *)(m))[-1].size)
588 #define REFFIELD(m) (((CmiChunkHeader *)(m))[-1].ref)
589 #define BLKSTART(m) (((CmiChunkHeader *)(m))-1)
590
591 extern void* malloc_nomigrate(size_t size);
592
593 void    *CmiAlloc(int size);
594 void     CmiReference(void *blk);
595 int      CmiSize(void *blk);
596 void     CmiFree(void *blk);
597
598 #ifndef CMI_TMP_SKIP
599 void *CmiTmpAlloc(int size);
600 void CmiTmpFree(void *);
601 #endif
602
603 /* Pool features */
604
605
606 /* Various special features of certain -memory modes: */
607 extern void * memory_stack_top; /* contains the top of the stack, for -memory charmdebug */
608 void CmiMemoryCheck(void); /* heap check, for -memory paranoid */
609 void CmiMemoryMark(void); /* ignore current allocations, for -memory leak */
610 void CmiMemoryMarkBlock(void *blk); /* ignore this allocation, for -memory leak */
611 void CmiMemorySweep(const char *where); /* print current allocations, for -memory leak */
612 CMK_TYPEDEF_UINT8 CmiMemoryUsage();
613 CMK_TYPEDEF_UINT8 CmiMaxMemoryUsage();
614 void CmiResetMaxMemory();
615 CMK_TYPEDEF_UINT8 CmiMinMemoryUsage();
616 void CmiResetMinMemory();
617
618 #define CMI_MEMORY_IS_ISOMALLOC (1<<1)
619 #define CMI_MEMORY_IS_PARANOID  (1<<2)
620 #define CMI_MEMORY_IS_GNU       (1<<3)
621 #define CMI_MEMORY_IS_GNUOLD    (1<<4)
622 int CmiMemoryIs(int flag); /* return state of this flag */
623
624 #define CMI_THREAD_IS_QT         (1<<1)
625 #define CMI_THREAD_IS_CONTEXT    (1<<2)
626 #define CMI_THREAD_IS_UJCONTEXT  (1<<3)
627 #define CMI_THREAD_IS_PTHREADS   (1<<4)
628 #define CMI_THREAD_IS_FIBERS     (1<<5)
629 #define CMI_THREAD_IS_ALIAS      (1<<6)
630 #define CMI_THREAD_IS_STACKCOPY  (1<<7)
631 int CmiThreadIs(int flag); /* return state of this flag */
632
633 void CmiMkdir(const char *dirName);
634
635 double   CmiCpuTimer(void);
636
637 #if CMK_TIMER_USE_RDTSC 
638 #ifndef __x86_64__
639 # if ! (CMK_GCC_X86_ASM || CMK_GCC_IA64_ASM)
640 /* Can't use rdtsc unless we have x86 or ia64 assembly: */
641 #  undef CMK_TIMER_USE_RDTSC
642 #  undef CMK_TIMER_USE_GETRUSAGE
643 #  define CMK_TIMER_USE_RDTSC 0
644 #  define CMK_TIMER_USE_GETRUSAGE 1
645 # endif
646 #endif
647 #endif
648
649 #if CMK_TIMER_USE_RDTSC 
650 extern double _cpu_speed_factor;
651
652 static __inline__ unsigned long long int rdtsc(void)
653 {
654         unsigned long long int x;
655 #ifdef __x86_64__
656         /* taken from papi code ("perfctr-p3.c") for machines like opteron */
657         do {
658           unsigned int a,d;
659           asm volatile("rdtsc" : "=a" (a), "=d" (d));
660           (x) = ((unsigned long)a) | (((unsigned long)d)<<32);
661         } while(0);
662 #elif CMK_GCC_IA64_ASM
663         __asm__ __volatile__("mov %0=ar.itc" : "=r"(x) :: "memory");
664 #elif CMK_GCC_X86_ASM
665         __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
666 #else
667 #  error "Unknown assembly format-- can't use CMK_TIMER_USE_RDTSC."
668 #endif
669         return x;
670 }
671
672 #define CmiWallTimer() ((double)rdtsc()*(_cpu_speed_factor))
673 #define CmiTimer CmiCpuTimer
674 double   CmiStartTimer(void);
675 #define CmiTimerIsSynchronized()        (0)
676
677 #else
678 void     CmiTimerInit();
679 double   CmiTimer(void);
680 double   CmiWallTimer(void);
681 #define  CmiStartTimer()                (0.0)
682 int      CmiTimerIsSynchronized();
683 #endif
684
685 #if CMK_NODE_QUEUE_AVAILABLE
686
687 #define CsdNodeEnqueueGeneral(x,s,i,p) do { \
688           CmiLock(CsvAccess(CsdNodeQueueLock));\
689           CqsEnqueueGeneral(CsvAccess(CsdNodeQueue),(x),(s),(i),(p)); \
690           CmiUnlock(CsvAccess(CsdNodeQueueLock)); \
691         } while(0)
692 #define CsdNodeEnqueueFifo(x)     do { \
693           CmiLock(CsvAccess(CsdNodeQueueLock));\
694           CqsEnqueueFifo(CsvAccess(CsdNodeQueue),(x)); \
695           CmiUnlock(CsvAccess(CsdNodeQueueLock)); \
696         } while(0)
697 #define CsdNodeEnqueueLifo(x)     do { \
698           CmiLock(CsvAccess(CsdNodeQueueLock));\
699           CqsEnqueueLifo(CsvAccess(CsdNodeQueue),(x))); \
700           CmiUnlock(CsvAccess(CsdNodeQueueLock)); \
701         } while(0)
702 #define CsdNodeEnqueue(x)     do { \
703           CmiLock(CsvAccess(CsdNodeQueueLock));\
704           CqsEnqueueFifo(CsvAccess(CsdNodeQueue),(x));\
705           CmiUnlock(CsvAccess(CsdNodeQueueLock)); \
706         } while(0)
707
708 #define CsdNodeEmpty()            (CqsEmpty(CpvAccess(CsdNodeQueue)))
709 #define CsdNodeLength()           (CqsLength(CpvAccess(CsdNodeQueue)))
710
711 #else
712
713 #define CsdNodeEnqueueGeneral(x,s,i,p) (CsdEnqueueGeneral(x,s,i,p))
714 #define CsdNodeEnqueueFifo(x) (CqsEnqueueFifo(CpvAccess(CsdSchedQueue),(x)))
715 #define CsdNodeEnqueueLifo(x) (CqsEnqueueLifo(CpvAccess(CsdSchedQueue),(x)))
716 #define CsdNodeEnqueue(x)     (CsdEnqueue(x))
717 #define CsdNodeEmpty()        (CqsEmpty(CpvAccess(CsdSchedQueue)))
718 #define CsdNodeLength()       (CqsLength(CpvAccess(CsdSchedQueue)))
719
720 #endif
721
722 #define CsdEnqueueGeneral(x,s,i,p)\
723     (CqsEnqueueGeneral(CpvAccess(CsdSchedQueue),(x),(s),(i),(p)))
724 #define CsdEnqueueFifo(x)     (CqsEnqueueFifo(CpvAccess(CsdSchedQueue),(x)))
725 #define CsdEnqueueLifo(x)     (CqsEnqueueLifo(CpvAccess(CsdSchedQueue),(x)))
726 #define CsdEnqueue(x)         (CqsEnqueueFifo(CpvAccess(CsdSchedQueue),(x)))
727 #define CsdEmpty()            (CqsEmpty(CpvAccess(CsdSchedQueue)))
728 #define CsdLength()           (CqsLength(CpvAccess(CsdSchedQueue)))
729
730 #if CMK_CMIPRINTF_IS_A_BUILTIN /* these are implemented in machine.c */
731 void  CmiPrintf(const char *, ...);
732 void  CmiError(const char *, ...);
733 int   CmiScanf(const char *, ...);
734 /* CmiFlush is disabled in this case */
735 #define CmiFlush(stream) 
736
737 #else /* standard definitions */
738
739 #include <stdio.h>
740
741 /*
742  * I made vprintf functions for CmiPrintf and CmiError, but on the
743  * O2K, there is no equivalent vscanf!
744
745  #define CmiPrintf printf
746  #define CmiError  printf
747 */
748 #include <stdarg.h>
749
750 void  CmiPrintf(const char *format, ...);
751 void  CmiError(const char *format, ...);
752 /* CmiFlush works only when CMK_CMIPRINTF_IS_A_BUILTIN is false */
753 #define CmiFlush(stream)  fflush(stream);
754 #define CmiScanf  scanf
755
756 #endif
757
758 #ifdef CMK_OPTIMIZE
759 #define CmiAssert(expr) ((void) 0)
760 #else
761 #if defined(__STDC__) || defined(__cplusplus)
762 #define __CMK_STRING(x) #x
763 #else
764 #define __CMK_STRING(x) "x"
765 #endif
766 extern void __cmi_assert(const char *, const char *, int);
767 #define CmiAssert(expr) \
768   ((void) ((expr) ? 0 :                   \
769      (__cmi_assert (__CMK_STRING(expr), __FILE__, __LINE__), 0)))
770 #endif
771
772 typedef void (*CmiStartFn)(int argc, char **argv);
773
774 /********* CSD - THE SCHEDULER ********/
775
776 CpvExtern(int, _ccd_numchecks);
777 extern void  CcdCallBacks();
778 #define CsdPeriodic() do{ if (CpvAccess(_ccd_numchecks)-- <= 0) CcdCallBacks(); } while(0)
779 #define CsdResetPeriodic()    CpvAccess(_ccd_numchecks) = 0;
780
781 extern void  CsdEndIdle(void);
782 extern void  CsdStillIdle(void);
783 extern void  CsdBeginIdle(void);
784
785 typedef struct {
786   void *localQ;
787   void *nodeQ;
788   void *schedQ;
789   int *localCounter;
790 #if CMK_OBJECT_QUEUE_AVAILABLE
791   void *objQ;
792 #endif
793   CmiNodeLock nodeLock;
794 #if CMK_GRID_QUEUE_AVAILABLE
795   void *gridQ;
796 #endif
797 } CsdSchedulerState_t;
798 extern void CsdSchedulerState_new(CsdSchedulerState_t *state);
799 extern void *CsdNextMessage(CsdSchedulerState_t *state);
800
801 extern void  *CmiGetNonLocal(void);
802 extern void   CmiNotifyIdle(void);
803
804 /*Different kinds of schedulers: generic, eternal, counting, polling*/
805 extern  int CsdScheduler(int maxmsgs);
806 extern void CsdScheduleForever(void);
807 extern  int CsdScheduleCount(int maxmsgs);
808 extern void CsdSchedulePoll(void);
809
810 #define CsdExitScheduler()  (CpvAccess(CsdStopFlag)++)
811
812 #if CMK_SPANTREE_USE_COMMON_CODE
813
814 #define CST_W  (CMK_SPANTREE_MAXSPAN)
815 #define CST_NN (CmiNumNodes())
816 #define CmiNodeSpanTreeParent(n) ((n)?(((n)-1)/CST_W):(-1))
817 #define CmiNodeSpanTreeChildren(n,c) do {\
818           int _i; \
819           for(_i=0; _i<CST_W; _i++) { \
820             int _x = (n)*CST_W+_i+1; \
821             if(_x<CST_NN) (c)[_i]=_x; \
822           }\
823         } while(0)
824 #define CmiNumNodeSpanTreeChildren(n) ((((n)+1)*CST_W<CST_NN)? CST_W : \
825           ((((n)*CST_W+1)>=CST_NN)?0:((CST_NN-1)-(n)*CST_W)))
826 #define CST_R(p) (CmiRankOf(p))
827 #define CST_NF(n) (CmiNodeFirst(n))
828 #define CST_SP(n) (CmiNodeSpanTreeParent(n))
829 #define CST_ND(p) (CmiNodeOf(p))
830 #define CST_NS(p) (CmiNodeSize(CST_ND(p)))
831 #define CmiSpanTreeParent(p) ((p)?(CST_R(p)?(CST_NF(CST_ND(p))+(CST_R(p)-1)/CST_W):CST_NF(CST_SP(CST_ND(p)))):(-1))
832 #define CST_C(p) (((CST_R(p)+1)*CST_W<CST_NS(p))?CST_W:(((CST_R(p)*CST_W+1)>=CST_NS(p))?0:((CST_NS(p)-1)-CST_R(p)*CST_W)))
833 #define CST_SC(p) (CmiNumNodeSpanTreeChildren(CST_ND(p)))
834 #define CmiNumSpanTreeChildren(p) (CST_R(p)?CST_C(p):(CST_SC(p)+CST_C(p)))
835 #define CmiSpanTreeChildren(p,c) do {\
836           int _i,_c=0; \
837           if(CST_R(p)==0) { \
838             for(_i=0;_i<CST_W;_i++) { \
839               int _x = CST_ND(p)*CST_W+_i+1; \
840               if(_x<CST_NN) (c)[_c++]=CST_NF(_x); \
841             }\
842           } \
843           for(_i=0;_i<CST_W;_i++) { \
844             int _x = CST_R(p)*CST_W+_i+1; \
845             if(_x<CST_NS(p)) (c)[_c++]=CST_NF(CST_ND(p))+_x; \
846           }\
847         } while(0)
848
849 #else
850
851 int      CmiNumSpanTreeChildren(int) ;
852 int      CmiSpanTreeParent(int) ;
853 void     CmiSpanTreeChildren(int node, int *children);
854 int      CmiNumNodeSpanTreeChildren(int);
855 int      CmiNodeSpanTreeParent(int) ;
856 void     CmiNodeSpanTreeChildren(int node, int *children) ;
857 #endif
858
859 /****** MULTICAST GROUPS ******/
860
861 typedef CMK_MULTICAST_GROUP_TYPE CmiGroup;
862
863 void     CmiGroupInit();
864 CmiGroup CmiEstablishGroup(int npes, int *pes);
865 void     CmiLookupGroup(CmiGroup grp, int *npes, int **pes);
866
867 /****** CMI MESSAGE TRANSMISSION ******/
868
869 /* Utility function: it packs a multiple chunk message into a singly one.
870  * Receives the two return values outsize and outdata to return the size of the
871  * composed message and the message itself. It receives the number of chunks to
872  * compact, their sizes and datas. The types of the parameters are:
873  *
874  * int outsize, inndata, insizes;
875  * char *outdata;
876  * char **indatas;
877  *
878  * If inndata is negative, it means that the messages need to be copied together
879  * with their memory header at the beginning (message nesting), and padded to 8
880  * bytes. The first message never has its memory header attached (it uses the
881  * one of the new message).
882  */
883
884 #define VECTOR_COMPACT(outsize,outdata,inndata,insizes,indatas,chunkHeaderSize) {\
885   int i;\
886   char *tmp;\
887   outsize=0;\
888   if (inndata>=0) for(i=0; i<inndata; ++i) outsize += insizes[i];\
889   else {\
890     for(i=0; i<-inndata; ++i) outsize += ALIGN8(insizes[i]);\
891     outsize -= (inndata+1) * chunkHeaderSize;\
892   }\
893   outdata = (char *)CmiAlloc(outsize);\
894   if (!outdata) fprintf(stderr, "%d: Out of mem\n", CmiMyNode());\
895   tmp = outdata;\
896   if (inndata>=0) {\
897     for (i=0; i<inndata; ++i) {\
898       memcpy(tmp, indatas[i], insizes[i]);\
899       tmp += insizes[i];\
900     }\
901   } else {\
902     memcpy(tmp, indatas[0], insizes[0]);\
903     tmp += ALIGN8(insizes[0]);\
904     for (i=0; i<-inndata; ++i) {\
905       memcpy(tmp, indatas[i]-chunkHeaderSize, insizes[i]+chunkHeaderSize);\
906       tmp += ALIGN8(insizes[i])+chunkHeaderSize;\
907     }\
908   }\
909 }
910
911 void          CmiSyncSendFn(int, int, char *);
912 CmiCommHandle CmiAsyncSendFn(int, int, char *);
913 void          CmiFreeSendFn(int, int, char *);
914
915 void          CmiSyncBroadcastFn(int, char *);
916 CmiCommHandle CmiAsyncBroadcastFn(int, char *);
917 void          CmiFreeBroadcastFn(int, char *);
918
919 void          CmiSyncBroadcastAllFn(int, char *);
920 CmiCommHandle CmiAsyncBroadcastAllFn(int, char *);
921 void          CmiFreeBroadcastAllFn(int, char *);
922
923 void          CmiSyncListSendFn(int, int *, int, char*);
924 CmiCommHandle CmiAsyncListSendFn(int, int *, int, char*);
925 void          CmiFreeListSendFn(int, int *, int, char*);
926
927 void          CmiSyncMulticastFn(CmiGroup, int, char*);
928 CmiCommHandle CmiAsyncMulticastFn(CmiGroup, int, char*);
929 void          CmiFreeMulticastFn(CmiGroup, int, char*);
930
931 typedef struct {
932   void *localMessage;
933   void *remoteMessages;
934   int numRemoteReceived;
935   int numChildren;
936   int parent;
937   struct {
938     CmiHandler destination;
939     void * (*mergeFn)(void*,void**,int);
940     void (*pupFn)(void*,void*);
941     void (*deleteFn)(void*);
942   } ops;
943 } CmiReduction;
944
945 void CmiReduce(void *msg, int size, void * (*mergeFn)(void*,void**,int));
946 void CmiReduceStruct(void *data, void (*pupFn)(void*,void*),
947                      void * (*mergeFn)(void*,void**,int), CmiHandler dest,
948                      void (*deleteFn)(void*));
949 void CmiNodeReduce(void *msg, int size, void * (*mergeFn)(void*,void**,int), int, int, int);
950 void CmiNodeReduceStruct(void *data, void (*pupFn)(void*,void*),
951                          void * (*mergeFn)(void*,void**,int), CmiHandler dest,
952                          void (*deleteFn)(void*));
953 void CmiHandleReductionMessage(void *msg);
954 int CmiGetReductionHandler();
955 CmiHandler CmiGetReductionDestination();
956
957 /* If the second parameter (the number of chunks to send) is negative, then
958  * every message will be started aligned with 8 bytes, and a message header will
959  * be preponed to every message (message nesting), except the first one which
960  * uses that of the entire message.
961  */
962 void          CmiSyncVectorSend(int, int, int *, char **);
963 CmiCommHandle CmiAsyncVectorSend(int, int, int *, char **);
964 void          CmiSyncVectorSendAndFree(int, int, int *, char **);
965
966 void          CmiMultipleSend(unsigned int, int, int *, char **);
967 void          CmiMultipleIsend(unsigned int, int, int *, char **);
968
969 int           CmiAsyncMsgSent(CmiCommHandle);
970 void          CmiReleaseCommHandle(CmiCommHandle);
971
972 #define CmiSyncSend(p,s,m)              (CmiSyncSendFn((p),(s),(char *)(m)))
973 #define CmiAsyncSend(p,s,m)             (CmiAsyncSendFn((p),(s),(char *)(m)))
974 #define CmiSyncSendAndFree(p,s,m)       (CmiFreeSendFn((p),(s),(char *)(m)))
975
976 #define CmiSyncBroadcast(s,m)           (CmiSyncBroadcastFn((s),(char *)(m)))
977 #define CmiAsyncBroadcast(s,m)          (CmiAsyncBroadcastFn((s),(char *)(m)))
978 #define CmiSyncBroadcastAndFree(s,m)    (CmiFreeBroadcastFn((s),(char *)(m)))
979
980 #define CmiSyncBroadcastAll(s,m)        (CmiSyncBroadcastAllFn((s),(char *)(m)))
981 #define CmiAsyncBroadcastAll(s,m)       (CmiAsyncBroadcastAllFn((s),(char *)(m)))
982 #define CmiSyncBroadcastAllAndFree(s,m) (CmiFreeBroadcastAllFn((s),(char *)(m)))
983
984 #define CmiSyncListSend(n,l,s,m)        (CmiSyncListSendFn((n),(l),(s),(char *)(m)))
985 #define CmiAsyncListSend(n,l,s,m)       (CmiAsyncListSendFn((n),(l),(s),(char *)(m)))
986 #define CmiSyncListSendAndFree(n,l,s,m) (CmiFreeListSendFn((n),(l),(s),(char *)(m)))
987
988 #define CmiSyncMulticast(g,s,m)         (CmiSyncMulticastFn((g),(s),(char*)(m)))
989 #define CmiAsyncMulticast(g,s,m)        (CmiAsyncMulticastFn((g),(s),(char*)(m)))
990 #define CmiSyncMulticastAndFree(g,s,m)  (CmiFreeMulticastFn((g),(s),(char*)(m)))
991
992 #if CMK_NODE_QUEUE_AVAILABLE
993 void          CmiSyncNodeSendFn(int, int, char *);
994 CmiCommHandle CmiAsyncNodeSendFn(int, int, char *);
995 void          CmiFreeNodeSendFn(int, int, char *);
996
997 void          CmiSyncNodeBroadcastFn(int, char *);
998 CmiCommHandle CmiAsyncNodeBroadcastFn(int, char *);
999 void          CmiFreeNodeBroadcastFn(int, char *);
1000
1001 void          CmiSyncNodeBroadcastAllFn(int, char *);
1002 CmiCommHandle CmiAsyncNodeBroadcastAllFn(int, char *);
1003 void          CmiFreeNodeBroadcastAllFn(int, char *);
1004 #endif
1005
1006 #if CMK_NODE_QUEUE_AVAILABLE
1007 #define CmiSyncNodeSend(p,s,m)          (CmiSyncNodeSendFn((p),(s),(char *)(m)))
1008 #define CmiAsyncNodeSend(p,s,m)             (CmiAsyncNodeSendFn((p),(s),(char *)(m)))
1009 #define CmiSyncNodeSendAndFree(p,s,m)       (CmiFreeNodeSendFn((p),(s),(char *)(m)))
1010 #define CmiSyncNodeBroadcast(s,m)           (CmiSyncNodeBroadcastFn((s),(char *)(m)))
1011 #define CmiAsyncNodeBroadcast(s,m)          (CmiAsyncNodeBroadcastFn((s),(char *)(m)))
1012 #define CmiSyncNodeBroadcastAndFree(s,m)    (CmiFreeNodeBroadcastFn((s),(char *)(m)))
1013 #define CmiSyncNodeBroadcastAll(s,m)        (CmiSyncNodeBroadcastAllFn((s),(char *)(m)))
1014 #define CmiAsyncNodeBroadcastAll(s,m)       (CmiAsyncNodeBroadcastAllFn((s),(char *)(m)))
1015 #define CmiSyncNodeBroadcastAllAndFree(s,m) (CmiFreeNodeBroadcastAllFn((s),(char *)(m)))
1016 #else
1017 #define CmiSyncNodeSend(n,s,m)        CmiSyncSend(CmiNodeFirst(n),s,m)
1018 #define CmiAsyncNodeSend(n,s,m)       CmiAsyncSend(CmiNodeFirst(n),s,m)
1019 #define CmiSyncNodeSendAndFree(n,s,m) CmiSyncSendAndFree(CmiNodeFirst(n),s,m)
1020 #define CmiSyncNodeBroadcast(s,m)           do { \
1021           int _i; \
1022           for(_i=0; _i<CmiNumNodes(); _i++) \
1023             if(_i != CmiMyNode()) \
1024               CmiSyncSend(CmiNodeFirst(_i),s,m); \
1025         } while(0)
1026 #define CmiAsyncNodeBroadcast(s,m)          CmiSyncNodeBroadcast(s,m)
1027 #define CmiSyncNodeBroadcastAndFree(s,m)    do { \
1028           CmiSyncNodeBroadcast(s,m); \
1029           CmiFree(m); \
1030         } while(0)
1031 #define CmiSyncNodeBroadcastAll(s,m)           do { \
1032           int _i; \
1033           for(_i=0; _i<CmiNumNodes(); _i++) \
1034             CmiSyncSend(CmiNodeFirst(_i),s,m); \
1035         } while(0)
1036 #define CmiAsyncNodeBroadcastAll(s,m)       CmiSyncNodeBroadcastAll(s,m)
1037 #define CmiSyncNodeBroadcastAllAndFree(s,m) do { \
1038           CmiSyncNodeBroadcastAll(s,m); \
1039           CmiFree(m); \
1040         } while(0)
1041 #endif
1042
1043 /******** CMI MESSAGE RECEPTION ********/
1044
1045 void   CmiDeliversInit();
1046 int    CmiDeliverMsgs(int maxmsgs);
1047 void   CmiDeliverSpecificMsg(int handler);
1048 void   CmiHandleMessage(void *msg);
1049
1050 /******** CQS: THE QUEUEING SYSTEM ********/
1051
1052 #define CQS_QUEUEING_FIFO 2
1053 #define CQS_QUEUEING_LIFO 3
1054 #define CQS_QUEUEING_IFIFO 4
1055 #define CQS_QUEUEING_ILIFO 5
1056 #define CQS_QUEUEING_BFIFO 6
1057 #define CQS_QUEUEING_BLIFO 7
1058 #define CQS_QUEUEING_LFIFO 8
1059 #define CQS_QUEUEING_LLIFO 9
1060
1061 /****** Isomalloc: Migratable Memory Allocation ********/
1062 /*Simple block-by-block interface:*/
1063 void *CmiIsomalloc(int sizeInBytes);
1064 void  CmiIsomallocPup(pup_er p,void **block);
1065 void  CmiIsomallocFree(void *block);
1066
1067 CmiInt8   CmiIsomallocLength(void *block);
1068 int   CmiIsomallocInRange(void *addr);
1069
1070 /*List-of-blocks interface:*/
1071 struct CmiIsomallocBlockList {/*Circular doubly-linked list of blocks:*/
1072         struct CmiIsomallocBlockList *prev,*next;
1073         /*actual data of block follows here...*/
1074 };
1075 typedef struct CmiIsomallocBlockList CmiIsomallocBlockList;
1076
1077 /*Build/pup/destroy an entire blockList.*/
1078 CmiIsomallocBlockList *CmiIsomallocBlockListNew(void);
1079 void CmiIsomallocBlockListPup(pup_er p,CmiIsomallocBlockList **l);
1080 void CmiIsomallocBlockListDelete(CmiIsomallocBlockList *l);
1081
1082 /*Allocate/free a block from this blockList*/
1083 void *CmiIsomallocBlockListMalloc(CmiIsomallocBlockList *l,int nBytes);
1084 void CmiIsomallocBlockListFree(void *doomedMallocedBlock);
1085
1086 /****** CTH: THE LOW-LEVEL THREADS PACKAGE ******/
1087
1088 typedef struct CthThreadStruct *CthThread;
1089 typedef struct {
1090   /*Start with a message header so threads can be enqueued 
1091     as messages (e.g., by CthEnqueueNormalThread in convcore.c)
1092   */
1093   char cmicore[CmiReservedHeaderSize];
1094   CthThread thread;
1095 } CthThreadToken;
1096
1097 CthThreadToken *CthGetToken(CthThread);
1098
1099 typedef void        (*CthVoidFn)();
1100 typedef void        (*CthAwkFn)(CthThreadToken *,int,
1101                                 int prioBits,unsigned int *prioptr);
1102 typedef CthThread   (*CthThFn)();
1103
1104 int        CthImplemented(void);
1105
1106 CthThread  CthPup(pup_er, CthThread);
1107
1108 CthThread  CthSelf(void);
1109 CthThread  CthCreate(CthVoidFn, void *, int);
1110 CthThread  CthCreateMigratable(CthVoidFn, void *, int);
1111 void       CthResume(CthThread);
1112 void       CthFree(CthThread);
1113
1114 void       CthSetSuspendable(CthThread, int);
1115 int        CthIsSuspendable(CthThread);
1116
1117 void       CthSuspend(void);
1118 void       CthAwaken(CthThread);
1119 void       CthAwakenPrio(CthThread, int, int, unsigned int *);
1120 void       CthSetStrategy(CthThread, CthAwkFn, CthThFn);
1121 void       CthSetStrategyDefault(CthThread);
1122 void       CthYield(void);
1123 void       CthYieldPrio(int,int,unsigned int*);
1124
1125 void       CthSetNext(CthThread t, CthThread next);
1126 CthThread  CthGetNext(CthThread t);
1127
1128 void       CthSwitchThread(CthThread t);
1129
1130 size_t     CthStackOffset(CthThread t, char *p);
1131 char     * CthPointer(CthThread t, size_t pos);
1132
1133 /* unimplemented: preemptive threads */
1134 void       CthAutoYield(CthThread t, int flag);
1135 double     CthAutoYieldFreq(CthThread t);
1136 void       CthAutoYieldBlock(void);
1137 void       CthAutoYieldUnblock(void);
1138
1139 /* Converse Thread Global (Ctg) global variable manipulation */
1140 typedef struct CtgGlobalStruct *CtgGlobals;
1141
1142 /** Initialize the globals support (called on each processor). */
1143 void CtgInit(void);
1144 /** PIC method used: 0 = nop, 1 = elfgot, 2 = elfcopy */
1145 CpvExtern(int, CmiPICMethod);
1146
1147 /** Copy the current globals into this new set */
1148 CtgGlobals CtgCreate(void);
1149 /** Install this set of globals. If g==NULL, returns to original globals. */
1150 void CtgInstall(CtgGlobals g);
1151 /** PUP this (not currently installed) globals set */
1152 CtgGlobals CtgPup(pup_er, CtgGlobals g);
1153 /** Delete this (not currently installed) set of globals. */
1154 void CtgFree(CtgGlobals g);
1155 /** Return the current global list */
1156 CtgGlobals CtgCurrentGlobals(void);
1157 void CtgInstall_var(CtgGlobals g, void *ptr);
1158 void CtgUninstall_var(CtgGlobals g, void *ptr);
1159
1160 /* The thread listener structure. The user must register one such listener
1161         if he wants to find out when a thread is suspended or when it starts running
1162         or gets destroyed. It can be used for tracing etc.
1163 */
1164
1165 struct CthThreadListener;
1166
1167 typedef void (*CthThreadListener_suspend)(struct CthThreadListener *l);
1168 typedef void (*CthThreadListener_resume)(struct CthThreadListener *l);
1169 typedef void (*CthThreadListener_free)(struct CthThreadListener *l);
1170
1171 struct CthThreadListener {
1172        /** This thread is about to block. */
1173        CthThreadListener_suspend suspend;
1174
1175        /** This thread is about to begin execution after blocking. */
1176        CthThreadListener_resume resume;
1177
1178        /** This thread is being destroyed.  */
1179        CthThreadListener_free free;
1180
1181        /** Pointer to listener-specific data (if needed).
1182            Set by listener.
1183        */
1184        void *data;
1185
1186        /** Pointer to the thread this listener controls.
1187            Set by CthAddListener.
1188         */
1189        CthThread thread;
1190
1191        /** The next listener, or NULL at end of chain.
1192            Set by CthAddListener, and used only by threads.c.
1193        */
1194        struct CthThreadListener *next;
1195 };
1196
1197 /**
1198   This listener is about to begin receiving suspend and
1199 resume events for this thread.  "suspend", "resume", "free",
1200 and "data" fields must all already be set.  When this thread
1201 exits, l->free will be called on this listener, which should
1202 deallocate the listener memory.
1203 */
1204 void CthAddListener(CthThread th,struct CthThreadListener *l);
1205
1206 /**
1207   This is function is inserted into .def.h after thread creation.
1208   It serves as an interface for the user to add the listeners 
1209   as needed. User has to implement this somewhere in the system.
1210 */
1211 void CthUserAddListeners(CthThread th);
1212
1213
1214 /****** CTH: THREAD-PRIVATE VARIABLES ******/
1215
1216 #if CMK_THREADS_REQUIRE_NO_CPV
1217
1218 #define CthCpvDeclare(t,v)    t v
1219 #define CthCpvExtern(t,v)     extern t v
1220 #define CthCpvStatic(t,v)     static t v
1221 #define CthCpvInitialize(t,v) do {} while(0)
1222 #define CthCpvAccess(x)       x
1223
1224 #else
1225
1226 #define CthCpvDeclare(t,v)    CpvDeclare(t,v)
1227 #define CthCpvExtern(t,v)     CpvExtern(t,v)
1228 #define CthCpvStatic(t,v)     CpvStaticDeclare(t,v)
1229 #define CthCpvInitialize(t,v) CpvInitialize(t,v)
1230 #define CthCpvAccess(x)       CpvAccess(x)
1231
1232 #endif
1233
1234 CthCpvExtern(char *,CthData);
1235 extern int CthRegister(int dataSize);
1236 extern void CthRegistered(int dataOffMax);
1237 extern char *CthGetData(CthThread t);
1238
1239 #define CtvDeclare(t,v)         typedef t CtvType##v; CsvDeclare(int,CtvOffs##v)=(-1)
1240 #define CtvStaticDeclare(t,v)   typedef t CtvType##v; CsvStaticDeclare(int,CtvOffs##v)=(-1)
1241 #define CtvExtern(t,v)          typedef t CtvType##v; CsvExtern(int,CtvOffs##v)
1242 #define CtvAccess(v)            (*((CtvType##v *)(CthCpvAccess(CthData)+CsvAccess(CtvOffs##v))))
1243 #define CtvAccessOther(t,v)            (*((CtvType##v *)(CthGetData(t)+CsvAccess(CtvOffs##v))))
1244 #define CtvInitialize(t,v)      do { \
1245         if(CsvAccess(CtvOffs##v)==(-1)) \
1246                 CsvAccess(CtvOffs##v)=CthRegister(sizeof(CtvType##v));\
1247         else CthRegistered(CsvAccess(CtvOffs##v)+sizeof(CtvType##v));\
1248 } while(0)
1249
1250 /****** CFUTURE: CONVERSE FUTURES ******/
1251
1252 typedef struct Cfuture_s
1253 {
1254   int pe;
1255   struct Cfuture_data_s *data;
1256 }
1257 Cfuture;
1258
1259 #define CfutureValueData(v) ((void*)((v)->rest))
1260
1261 Cfuture       CfutureCreate(void);
1262 void          CfutureSet(Cfuture f, void *val, int len);
1263 void         *CfutureWait(Cfuture f);
1264 void          CfutureDestroy(Cfuture f);
1265
1266 void         *CfutureCreateBuffer(int bytes);
1267 void          CfutureDestroyBuffer(void *val);
1268 void          CfutureStoreBuffer(Cfuture f, void *value);
1269
1270 #define       CfuturePE(f) ((f).pe)
1271
1272 void CfutureInit();
1273
1274 /****** CLD: THE LOAD BALANCER ******/
1275
1276 #define CLD_ANYWHERE (-1)
1277 #define CLD_BROADCAST (-2)
1278 #define CLD_BROADCAST_ALL (-3)
1279
1280 typedef void (*CldPackFn)(void *msg);
1281
1282 typedef void (*CldInfoFn)(void *msg, 
1283                           CldPackFn *packer,
1284                           int *len,
1285                           int *queueing,
1286                           int *priobits, 
1287                           unsigned int **prioptr);
1288
1289 typedef int (*CldEstimator)(void);
1290
1291 int CldRegisterInfoFn(CldInfoFn fn);
1292 int CldRegisterPackFn(CldPackFn fn);
1293 void CldRegisterEstimator(CldEstimator fn);
1294 int CldEstimate(void);
1295 char *CldGetStrategy(void);
1296
1297 void CldEnqueue(int pe, void *msg, int infofn);
1298 void CldEnqueueMulti(int npes, int *pes, void *msg, int infofn);
1299 void CldNodeEnqueue(int node, void *msg, int infofn);
1300
1301 /****** CMM: THE MESSAGE MANAGER ******/
1302
1303 typedef struct CmmTableStruct *CmmTable;
1304
1305 #define CmmWildCard (-1)
1306
1307 typedef void (*CmmPupMessageFn)(pup_er p,void **msg);
1308 CmmTable CmmPup(pup_er p, CmmTable t, CmmPupMessageFn msgpup);
1309
1310 CmmTable   CmmNew();
1311 void       CmmFree(CmmTable t);
1312 void       CmmPut(CmmTable t, int ntags, int *tags, void *msg);
1313 void      *CmmFind(CmmTable t, int ntags, int *tags, int *returntags, int del);
1314 int        CmmEntries(CmmTable t);
1315 int        CmmGetLastTag(CmmTable t, int ntags, int *tags);
1316 #define    CmmGet(t,nt,tg,rt)   (CmmFind((t),(nt),(tg),(rt),1))
1317 #define    CmmProbe(t,nt,tg,rt) (CmmFind((t),(nt),(tg),(rt),0))
1318
1319 /******** ConverseInit and ConverseExit ********/
1320
1321 void ConverseInit(int, char**, CmiStartFn, int, int);
1322 void ConverseExit(void);
1323
1324 void CmiAbort(const char *);
1325 void CmiOutOfMemory(int nBytes);
1326
1327 #if CMK_MEMCHECK_OFF
1328 #define _MEMCHECK(p) do{}while(0)
1329 #else
1330 #define _MEMCHECK(p) do { \
1331                          if ((p)==0) CmiOutOfMemory(-1);\
1332                      } while(0)
1333 #endif
1334
1335 /******** CONVCONDS ********/
1336
1337 typedef void (*CcdVoidFn)(void *userParam,double curWallTime);
1338
1339 /*CPU conditions*/
1340 #define CcdPROCESSOR_BEGIN_BUSY 0
1341 #define CcdPROCESSOR_END_IDLE 0 /*Synonym*/
1342 #define CcdPROCESSOR_BEGIN_IDLE 1
1343 #define CcdPROCESSOR_END_BUSY 1 /*Synonym*/
1344 #define CcdPROCESSOR_STILL_IDLE 2
1345
1346 /*Periodic calls*/
1347 #define CcdPERIODIC       16 /*every few ms*/
1348 #define CcdPERIODIC_10ms  17 /*every 10ms (100Hz)*/
1349 #define CcdPERIODIC_100ms 18 /*every 100ms (10Hz)*/
1350 #define CcdPERIODIC_1second  19 /*every second*/
1351 #define CcdPERIODIC_1s       19 /*every second*/
1352 #define CcdPERIODIC_10second 20 /*every 10 seconds*/
1353 #define CcdPERIODIC_10seconds 20 /*every 10 seconds*/
1354 #define CcdPERIODIC_10s      20 /*every 10 seconds*/
1355 #define CcdPERIODIC_1minute  21 /*every minute*/
1356 #define CcdPERIODIC_10minute 22 /*every 10 minutes*/
1357 #define CcdPERIODIC_1hour    23 /*every hour*/
1358 #define CcdPERIODIC_12hour   24 /*every 12 hours*/
1359 #define CcdPERIODIC_1day     25 /*every day*/
1360
1361 /*Other conditions*/
1362 #define CcdQUIESCENCE 30
1363 #define CcdSIGUSR1 32+1
1364 #define CcdSIGUSR2 32+2
1365
1366 /*User-defined conditions start here*/
1367 #define CcdUSER    48
1368
1369 #define CcdIGNOREPE   -2
1370 #if CMK_CONDS_USE_SPECIAL_CODE
1371 typedef int (*CmiSwitchToPEFnPtr)(int pe);
1372 extern CmiSwitchToPEFnPtr CmiSwitchToPE;
1373 #else
1374 #define CmiSwitchToPE(pe)  pe
1375 #endif
1376 void CcdCallFnAfter(CcdVoidFn fnp, void *arg, double msecs);
1377 int CcdCallOnCondition(int condnum, CcdVoidFn fnp, void *arg);
1378 int CcdCallOnConditionKeep(int condnum, CcdVoidFn fnp, void *arg);
1379 void CcdCallFnAfterOnPE(CcdVoidFn fnp, void *arg, double msecs, int pe);
1380 int CcdCallOnConditionOnPE(int condnum, CcdVoidFn fnp, void *arg, int pe);
1381 int CcdCallOnConditionKeepOnPE(int condnum, CcdVoidFn fnp, void *arg, int pe);
1382 void CcdCancelCallOnCondition(int condnum, int idx);
1383 void CcdCancelCallOnConditionKeep(int condnum, int idx);
1384 void CcdRaiseCondition(int condnum);
1385
1386 /* Command-Line-Argument handling */
1387 void CmiArgGroup(const char *parentName,const char *groupName);
1388 int CmiGetArgInt(char **argv,const char *arg,int *optDest);
1389 int CmiGetArgIntDesc(char **argv,const char *arg,int *optDest,const char *desc);
1390 int CmiGetArgDouble(char **argv,const char *arg,double *optDest);
1391 int CmiGetArgDoubleDesc(char **argv,const char *arg,double *optDest,const char *desc);
1392 int CmiGetArgString(char **argv,const char *arg,char **optDest);
1393 int CmiGetArgStringDesc(char **argv,const char *arg,char **optDest,const char *desc);
1394 int CmiGetArgFlag(char **argv,const char *arg);
1395 int CmiGetArgFlagDesc(char **argv,const char *arg,const char *desc);
1396 void CmiDeleteArgs(char **argv,int k);
1397 int CmiGetArgc(char **argv);
1398 char **CmiCopyArgs(char **argv);
1399 int CmiArgGivingUsage(void);
1400
1401 /** 
1402    Extract the function-return pointers listed in the stack
1403    up to this depth.  nSkip is the number of enclosing functions
1404    to skip-- for example, nSkip==0 means the retPtrs[0]
1405    will be the caller of CmiBacktraceRecord.  
1406    Returns retPtrs[0..*nLevels-1] stack pointers.
1407    *nLevels may be decreased if not enough levels are available.
1408  */
1409 void CmiBacktraceRecord(void **retPtrs,int nSkip,int *nLevels);
1410
1411 /** Look up the names of these function pointers.
1412 Caller must free() the returned array, but not the individual
1413 strings.
1414 */
1415 char **CmiBacktraceLookup(void **srcPtrs,int nLevels);
1416
1417 /** Print out the names of these function pointers. */
1418 void CmiBacktracePrint(void **retPtrs,int nLevels);
1419
1420 /* Print (to stdout) the names of the functions that have been 
1421    called up to this point. nSkip is the number of routines on the
1422    top of the stack to *not* print out. */
1423 void CmiPrintStackTrace(int nSkip);
1424 int CmiIsFortranLibraryCall();
1425
1426 #if CMK_CMIDELIVERS_USE_COMMON_CODE
1427 CpvExtern(void*, CmiLocalQueue);
1428 #endif
1429
1430 char *CmiCopyMsg(char *msg, int len);
1431
1432 /******** Hypercube broadcast propagation (Binomial tree) ********/
1433
1434 /*
1435   This routing will receive a number k containing the dimension in the hypercube
1436   to be used for the broadcast, i.e. k=0 means sending only to MyPe^1, k=1 means
1437   sending to MyPe^2 and MyPe^1, etc.
1438   The array dest_pes will be filled with the id of the processors to which send,
1439   it has to be already allocated, the size should be at least k+1 to allow
1440   enough space.
1441   It return the number of processors to which send, i.e. the size of dest_pes.
1442   This may be less than k+1 due to not complete hypercubes.
1443   For example with pow(2,n)+2 procs and 0 broadcasting, proc pow(2,n) will
1444   receive from 0 in the first step but then it has only proc pow(2,n)+1 as
1445   destination, so most of the other dimentions will be skipped.
1446 */
1447 int HypercubeGetBcastDestinations(int mype, int total_pes, int k, int *dest_pes);
1448
1449 /******** Immediate Messages ********/
1450
1451 CpvExtern(int, CmiImmediateMsgHandlerIdx);
1452
1453
1454 CpvExtern(unsigned, networkProgressCount);
1455 extern int networkProgressPeriod;
1456
1457 #if !CMK_MACHINE_PROGRESS_DEFINED
1458
1459 #define CmiNetworkProgress() 
1460 #define CmiNetworkProgressAfter(p) 
1461 #define CmiMachineProgressImpl()
1462
1463 #else
1464
1465 /*#ifdef __cplusplus
1466 extern "C" 
1467 #endif*/
1468 void CmiMachineProgressImpl();
1469
1470 #define CmiNetworkProgress() {CpvAccess(networkProgressCount) ++; \
1471       if(CpvAccess(networkProgressCount) >=  networkProgressPeriod) { \
1472           CmiMachineProgressImpl(); \
1473           CpvAccess(networkProgressCount) = 0; \
1474       } \
1475 } \
1476
1477 #define CmiNetworkProgressAfter(p) {CpvAccess(networkProgressCount) ++; \
1478       if(CpvAccess(networkProgressCount) >=  p) { \
1479           CmiMachineProgressImpl(); \
1480           CpvAccess(networkProgressCount) = 0; \
1481       } \
1482 } \
1483
1484 #endif
1485
1486 #define CmiProbeImmediateMsg CmiMachineProgressImpl
1487
1488 /*
1489    to immediate-fy a Converse message, set the most significant bit to 1
1490    in the Converse handler (x|0x8000). 
1491 */
1492 #if CMK_IMMEDIATE_MSG
1493 void CmiDelayImmediate();
1494 #  define CmiBecomeImmediate(msg) do { \
1495         CmiSetHandler(msg, (CmiGetHandler(msg))|0x8000); \
1496      } while (0)
1497 #  define CmiIsImmediate(msg)      ((CmiGetHandler(msg)) & 0x8000) 
1498 #  define CmiImmediateHandler(msg) ((CmiGetHandler(msg)) ^ 0x8000)
1499 /*
1500 #  define CmiIsImmediate(msg)   ((CmiGetHandler(msg) == CpvAccessOther(CmiImmediateMsgHandlerIdx,0)))
1501 #  define CmiBecomeImmediate(msg) do {\
1502         CmiSetXHandler(msg,CmiGetHandler(msg)); \
1503         CmiSetHandler(msg,CpvAccessOther(CmiImmediateMsgHandlerIdx,0)); \
1504      } while (0)
1505 #  define CmiImemdiateHandler(msg) (CmiGetXHandler(msg))
1506 */
1507 /* 
1508   for non smp and non intr based version, it returns _immRunning
1509   for smp, this doesnot matter - CkMyPe() comparasion normaly fails and
1510            non threadsafe CqsEnqueueGeneral is avoided.
1511 */
1512 #if CMK_NET_VERSION && ! CMK_SMP
1513 extern int _immRunning;
1514 #  define CmiImmIsRunning()        (_immRunning)
1515 #else
1516 #  define CmiImmIsRunning()        (0)
1517 #endif
1518
1519 #else
1520 #  define CmiBecomeImmediate(msg) /* empty */
1521 #  define CmiIsImmediate(msg)   (0)
1522 #  define CmiImmIsRunning()       (0)
1523 #endif
1524
1525 /******** Memory Fence ********/
1526
1527 #if  CMK_AMD64
1528 #define smp_rmb()    asm volatile("lfence":::"memory")
1529 #define smp_wmb()    asm volatile("sfence" ::: "memory")
1530 #else
1531 #define smp_rmb()
1532 #define smp_wmb()
1533 #endif
1534
1535 /** Atomically increment/decrement this integer. */
1536 #ifdef CMK_CPV_IS_SMP
1537 #if CMK_AMD64 || CMK_GCC_X86_ASM
1538 #define CmiMemoryAtomicIncrement(someInt) asm("lock incl %0" :: "m" (someInt))
1539 #define CmiMemoryAtomicDecrement(someInt) asm("lock decl %0" :: "m" (someInt))
1540 #else
1541 #define CmiMemoryAtomicIncrement(someInt) someInt=someInt+1
1542 #define CmiMemoryAtomicDecrement(someInt) someInt=someInt-1
1543 #endif
1544 #else
1545 #define CmiMemoryAtomicIncrement(someInt)  someInt=someInt+1
1546 #define CmiMemoryAtomicDecrement(someInt)  someInt=someInt-1
1547 #endif
1548
1549 /******** Performance Counters ********/
1550 void CmiInitCounters();
1551 void CmiStartCounters(int events[], int numEvents);
1552 void CmiStopCounters(int events[], CMK_TYPEDEF_INT8 values[], int numEvents);
1553
1554 /******** Trace ********/
1555
1556 /* this is the type for thread ID, mainly used for projection. */
1557 typedef struct _CmiObjId {
1558 int id[4];
1559 #if defined(__cplusplus)
1560  _CmiObjId() { id[0] = id[1] = id[2] = id[3] = -1; }
1561   int isNull() { return id[0] == -1 && id[1] == -1 && 
1562                    id[2] == -1 && id[3] == -1; }
1563 #endif
1564 } CmiObjId;
1565
1566 /* public interface for thread id acquisition */
1567 CmiObjId *CthGetThreadID(CthThread th);
1568 void CthSetThreadID(CthThread th, int a, int b, int c);
1569
1570 void CthTraceResume(CthThread t);
1571
1572 /*FAULT_EVAC */
1573 #if CMK_BLUEGENE_CHARM
1574 #define CmiNodeAlive(x) (1)
1575 #else
1576 CpvExtern(char *,_validProcessors);
1577 #define CmiNodeAlive(x)  (CpvAccess(_validProcessors)[x])
1578 #endif
1579
1580
1581 #include "conv-cpm.h"
1582 #include "conv-cpath.h"
1583 #include "conv-qd.h"
1584 #include "conv-random.h"
1585 #include "conv-lists.h"
1586 #include "conv-trace.h"
1587 #include "persistent.h"
1588 #if CMK_CELL
1589 #include "cell-api.h"
1590 #endif
1591 #ifdef __ONESIDED_IMPL
1592 #include "conv-onesided.h"
1593 #endif
1594
1595 #if defined(__cplusplus)
1596 }
1597 #endif
1598
1599 #if CMK_GRID_QUEUE_AVAILABLE
1600 #if defined(__cplusplus)
1601 extern "C" int CmiGetCluster (int pe);
1602 extern "C" int CmiGridQueueGetInterval ();
1603 extern "C" int CmiGridQueueGetThreshold ();
1604 extern "C" void CmiGridQueueRegister (int gid, int nInts, int index1, int index2, int index3);
1605 extern "C" void CmiGridQueueDeregister (int gid, int nInts, int index1, int index2, int index3);
1606 extern "C" void CmiGridQueueDeregisterAll ();
1607 extern "C" int CmiGridQueueLookup (int gid, int nInts, int index1, int index2, int index3);
1608 extern "C" int CmiGridQueueLookupMsg (char *msg);
1609 #else
1610 extern int CmiGetCluster (int pe);
1611 extern int CmiGridQueueGetInterval ();
1612 extern int CmiGridQueueGetThreshold ();
1613 extern void CmiGridQueueRegister (int gid, int nInts, int index1, int index2, int index3);
1614 extern void CmiGridQueueDeregister (int gid, int nInts, int index1, int index2, int index3);
1615 extern void CmiGridQueueDeregisterAll ();
1616 extern int CmiGridQueueLookup (int gid, int nInts, int index1, int index2, int index3);
1617 extern int CmiGridQueueLookupMsg (char *msg);
1618 #endif
1619 #endif
1620
1621 #include "debug-conv.h"
1622
1623
1624 #endif /* CONVERSE_H */