Merge branch 'charm' of charmgit:charm into charm-mpi-interop
[charm.git] / src / ck-core / init.C
1 /**
2 \addtogroup CkInit
3 \brief Controls the Charm++ startup process.
4
5 This file runs the entire Charm++ startup process.
6
7 The process begins with every processor finishing the 
8 Converse startup process and calling _initCharm.
9 This routine runs almost the entire Charm++ setup process.
10 It begins by setting up various Cpvs and subsystems.
11
12 The rank 0 processor of each node then does
13 the Charm++ registration, by calling the various _register
14 routines.  
15
16 Now processor 0:
17 <ol>
18 <li>Creates each mainchare, by allocating the chares
19  and calling their constructors with argc/argv.
20  This typically results in a number of chare/group creations.
21 <li>Sends off all readonly data to the other processors.
22 </ol>
23 After _initCharm, processor 0 immediately begins work.
24
25 The other processors, however, must wait until they recieve 
26 the readonly data and all group creations.  They do this by 
27 setting the _charmHandlerIdx to a special "_bufferHandler"
28 which simply saves all normal messages into a special queue.  
29
30 As the startup data (readonlies and group creations) streams
31 into _initHandler, it counts messages until it is fully 
32 initialized, then calls _initDone to clean out the queues 
33 and resume normal operation.  
34
35 Upon resume of normal operation, the user code is guaranteed that
36 all readonlies (both data and messages) have been set consistently
37 on all processors, and that the constructors for all nodegroups
38 and groups allocated from a mainchare have been called.
39
40 It is not guaranteed the order in which (node)groups allocated
41 outside of a mainchare are constructed, nor that the construction
42 will happen before other messages have been delivered by the scheduler.
43
44 Even though not exposed to the final users, the creation order of
45 groups and nodegroups allocated in mainchares is deterministic and
46 respects the following points:
47 <ul>
48 <li>On all processors, there is no guarantee of the order of creation
49 between (node)groups allocated from different mainchares;
50 <li>On processor zero, within a mainchare, all (node)groups are created
51 in the order specified by the source code (strictly), including array
52 allocation of initial elements;
53 <li>On processors other than zero, within a mainchare, the order
54 specified by the source code is maintained between different nodegroups
55 and between different groups;
56 <li>On processors other than zero, the ordering between groups and
57 nodegroups is NOT maintained, as all nodegroups are created before any
58 group is created.
59 </ul>
60
61 This process should not have race conditions, but it can
62 never be excluded...
63 */
64 /*@{*/
65
66 #include "ck.h"
67 #include "trace.h"
68
69 void CkRestartMain(const char* dirname);
70 int storeInterOperateStatus = 0;
71
72 #define  DEBUGF(x)     //CmiPrintf x;
73
74 #ifdef CALCULATE_HOPS
75 /** Turn on manually if you want to calculate hops from within Charm++
76 for some application **/
77
78 #include "TopoManager.h"
79
80 TopoManager *tmgr = NULL;
81 double hops = 0;
82
83 extern "C" void calculateTotalHops(int pe1, int pe2, int size) {
84   if(tmgr == NULL)
85     tmgr = new TopoManager();
86   hops += (tmgr->getHopsBetweenRanks(pe1, pe2) * size);
87 }
88
89 extern "C" void printTotalHops() {
90   CmiPrintf("TOTAL HOPS %lf\n", hops/(1024*1024) );
91 }
92 #endif
93
94 UChar _defaultQueueing = CK_QUEUEING_FIFO;
95
96 UInt  _printCS = 0;
97 UInt  _printSS = 0;
98
99 /**
100  * This value has the number of total initialization message a processor awaits.
101  * It is received on nodes other than zero together with the ROData message.
102  * Even though it is shared by all processors it is ok: it doesn't matter when and
103  * by who it is set, provided that it becomes equal to the number of awaited messages
104  * (which is always at least one ---the readonly data message).
105  */
106 UInt  _numExpectInitMsgs = 0;
107 /**
108  * This number is used only by processor zero to count how many messages it will
109  * send out for the initialization process. After the readonly data message is sent
110  * (containing this counter), its value becomes irrelevant.
111  */
112 UInt  _numInitMsgs = 0;
113 /**
114  * Count the number of nodegroups that have been created in mainchares.
115  * Since the nodegroup creation is executed by a single processor in a
116  * given node, this value must be seen by all processors in a node.
117  */
118 CksvDeclare(UInt,_numInitNodeMsgs);
119 int   _infoIdx;
120 int   _charmHandlerIdx;
121 int   _initHandlerIdx;
122 int   _roRestartHandlerIdx;
123 int   _bocHandlerIdx;
124 int   _qdHandlerIdx;
125 int   _qdCommHandlerIdx;
126 int   _triggerHandlerIdx;
127 int   _mainDone = 0;
128 CksvDeclare(int, _triggersSent);
129
130 CkOutStream ckout;
131 CkErrStream ckerr;
132 CkInStream  ckin;
133
134 CkpvDeclare(void*,       _currentChare);
135 CkpvDeclare(int,         _currentChareType);
136 CkpvDeclare(CkGroupID,   _currentGroup);
137 CkpvDeclare(void*,       _currentNodeGroupObj);
138 CkpvDeclare(CkGroupID,   _currentGroupRednMgr);
139 CkpvDeclare(GroupTable*, _groupTable);
140 CkpvDeclare(GroupIDTable*, _groupIDTable);
141 CkpvDeclare(CmiImmediateLockType, _groupTableImmLock);
142 CkpvDeclare(UInt, _numGroups);
143
144 CkpvDeclare(CkCoreState *, _coreState);
145
146 CksvDeclare(UInt, _numNodeGroups);
147 CksvDeclare(GroupTable*, _nodeGroupTable);
148 CksvDeclare(GroupIDTable, _nodeGroupIDTable);
149 CksvDeclare(CmiImmediateLockType, _nodeGroupTableImmLock);
150 CksvDeclare(CmiNodeLock, _nodeLock);
151 CksvStaticDeclare(PtrVec*,_nodeBocInitVec);
152 CkpvDeclare(int, _charmEpoch);
153
154 CkpvDeclare(Stats*, _myStats);
155 CkpvDeclare(MsgPool*, _msgPool);
156
157 CkpvDeclare(_CkOutStream*, _ckout);
158 CkpvDeclare(_CkErrStream*, _ckerr);
159
160 CkpvStaticDeclare(int,  _numInitsRecd);
161 CkpvStaticDeclare(PtrQ*, _buffQ);
162 CkpvStaticDeclare(PtrVec*, _bocInitVec);
163
164
165 /*
166         FAULT_EVAC
167 */
168 CpvCExtern(char *, _validProcessors);
169 CkpvDeclare(char ,startedEvac);
170
171 int    _exitHandlerIdx;
172
173 #if CMK_WITH_STATS
174 static Stats** _allStats = 0;
175 #endif
176 static int   _numStatsRecd = 0;
177 static int   _exitStarted = 0;
178
179 static InitCallTable _initCallTable;
180
181 #if CMK_WITH_STATS
182 #define _STATS_ON(x) (x) = 1
183 #else
184 #define _STATS_ON(x) \
185           if (CkMyPe()==0) CmiPrintf("stats unavailable in optimized version. ignoring...\n");
186 #endif
187
188 // fault tolerance
189 typedef void (*CkFtFn)(const char *, CkArgMsg *);
190 static CkFtFn  faultFunc = NULL;
191 static char* _restartDir;
192
193 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
194 int teamSize=1;
195 int chkptPeriod=1000;
196 bool fastRecovery = false;
197 int parallelRecovery = 1;
198 extern int BUFFER_TIME; //time spent waiting for buffered messages
199 #endif
200
201 // flag for killing processes 
202 extern int killFlag;
203 // file specifying the processes to be killed
204 extern char *killFile;
205 // function for reading the kill file
206 void readKillFile();
207
208
209 int _defaultObjectQ = 0;            // for obejct queue
210 int _ringexit = 0;                  // for charm exit
211 int _ringtoken = 8;
212
213
214 /*
215         FAULT_EVAC
216
217         flag which marks whether or not to trigger the processor shutdowns
218 */
219 static int _raiseEvac=0;
220 static char *_raiseEvacFile;
221 void processRaiseEvacFile(char *raiseEvacFile);
222
223 static inline void _parseCommandLineOpts(char **argv)
224 {
225   if (CmiGetArgFlagDesc(argv,"+cs", "Print extensive statistics at shutdown"))
226       _STATS_ON(_printCS);
227   if (CmiGetArgFlagDesc(argv,"+ss", "Print summary statistics at shutdown"))
228       _STATS_ON(_printSS);
229   if (CmiGetArgFlagDesc(argv,"+fifo", "Default to FIFO queuing"))
230       _defaultQueueing = CK_QUEUEING_FIFO;
231   if (CmiGetArgFlagDesc(argv,"+lifo", "Default to LIFO queuing"))
232       _defaultQueueing = CK_QUEUEING_LIFO;
233   if (CmiGetArgFlagDesc(argv,"+ififo", "Default to integer-prioritized FIFO queuing"))
234       _defaultQueueing = CK_QUEUEING_IFIFO;
235   if (CmiGetArgFlagDesc(argv,"+ilifo", "Default to integer-prioritized LIFO queuing"))
236       _defaultQueueing = CK_QUEUEING_ILIFO;
237   if (CmiGetArgFlagDesc(argv,"+bfifo", "Default to bitvector-prioritized FIFO queuing"))
238       _defaultQueueing = CK_QUEUEING_BFIFO;
239   if (CmiGetArgFlagDesc(argv,"+blifo", "Default to bitvector-prioritized LIFO queuing"))
240       _defaultQueueing = CK_QUEUEING_BLIFO;
241   if (CmiGetArgFlagDesc(argv,"+objq", "Default to use object queue for every obejct"))
242   {
243 #if CMK_OBJECT_QUEUE_AVAILABLE
244       _defaultObjectQ = 1;
245       if (CkMyPe()==0)
246         CmiPrintf("Charm++> Create object queue for every Charm object.\n");
247 #else
248       CmiAbort("Charm++> Object queue not enabled, recompile Charm++ with CMK_OBJECT_QUEUE_AVAILABLE defined to 1.");
249 #endif
250   }
251   if(CmiGetArgString(argv,"+restart",&_restartDir))
252       faultFunc = CkRestartMain;
253 #if __FAULT__
254   if (CmiGetArgIntDesc(argv,"+restartaftercrash",&CpvAccess(_curRestartPhase),"restarting this processor after a crash")){      
255 # if CMK_MEM_CHECKPOINT
256       faultFunc = CkMemRestart;
257 # endif
258 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
259       faultFunc = CkMlogRestart;
260 #endif
261       CmiPrintf("[%d] Restarting after crash \n",CmiMyPe());
262   }
263   // reading the killFile
264   if(CmiGetArgStringDesc(argv,"+killFile", &killFile,"Generates SIGKILL on specified processors")){
265     if(faultFunc == NULL){
266       //do not read the killfile if this is a restarting processor
267       killFlag = 1;
268       if(CmiMyPe() == 0){
269         printf("[%d] killFlag set to 1 for file %s\n",CkMyPe(),killFile);
270       }
271     }
272   }
273 #endif
274
275   // shut down program in ring fashion to allow projections output w/o IO error
276   if (CmiGetArgIntDesc(argv,"+ringexit",&_ringtoken, "Program exits in a ring fashion")) 
277   {
278     _ringexit = 1;
279     if (CkMyPe()==0)
280       CkPrintf("Charm++> Program shutdown in token ring (%d).\n", _ringtoken);
281     if (_ringtoken > CkNumPes())  _ringtoken = CkNumPes();
282   }
283         /*
284                 FAULT_EVAC
285
286                 if the argument +raiseevac is present then cause faults
287         */
288         if(CmiGetArgStringDesc(argv,"+raiseevac", &_raiseEvacFile,"Generates processor evacuation on random processors")){
289                 _raiseEvac = 1;
290         }
291 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
292         if(!CmiGetArgIntDesc(argv,"+teamSize",&teamSize,"Set the team size for message logging")){
293         teamSize = 1;
294     }
295     if(!CmiGetArgIntDesc(argv,"+chkptPeriod",&chkptPeriod,"Set the checkpoint period for the message logging fault tolerance algorithm in seconds")){
296         chkptPeriod = 100;
297     }
298         if(CmiGetArgIntDesc(argv,"+fastRecovery", &parallelRecovery, "Parallel recovery with message logging protocol")){
299         fastRecovery = true;
300     }
301 #endif
302
303 #if defined(_FAULT_MLOG_)
304     if(!CmiGetArgIntDesc(argv,"+mlog_local_buffer",&_maxBufferedMessages,"# of local messages buffered in the message logging protoocl")){
305         _maxBufferedMessages = 2;
306     }
307     if(!CmiGetArgIntDesc(argv,"+mlog_remote_buffer",&_maxBufferedTicketRequests,"# of remote ticket requests buffered in the message logging protoocl")){
308         _maxBufferedTicketRequests = 2;
309     }
310     if(!CmiGetArgIntDesc(argv,"+mlog_buffer_time",&BUFFER_TIME,"# Time spent waiting for messages to be buffered in the message logging protoocl")){
311         BUFFER_TIME = 2;
312     }
313 #endif  
314         /* Anytime migration flag */
315         _isAnytimeMigration = true;
316         if (CmiGetArgFlagDesc(argv,"+noAnytimeMigration","The program does not require support for anytime migration")) {
317           _isAnytimeMigration = false;
318         }
319         
320         _isNotifyChildInRed = true;
321         if (CmiGetArgFlagDesc(argv,"+noNotifyChildInReduction","The program has at least one element per processor for each charm array created")) {
322           _isNotifyChildInRed = false;
323         }
324
325         _isStaticInsertion = false;
326         if (CmiGetArgFlagDesc(argv,"+staticInsertion","Array elements are only inserted at construction")) {
327           _isStaticInsertion = true;
328         }
329
330 #if ! CMK_WITH_CONTROLPOINT
331         // Display a warning if charm++ wasn't compiled with control point support but user is expecting it
332         if( CmiGetArgFlag(argv,"+CPSamplePeriod") || 
333             CmiGetArgFlag(argv,"+CPSamplePeriodMs") || 
334             CmiGetArgFlag(argv,"+CPSchemeRandom") || 
335             CmiGetArgFlag(argv,"+CPExhaustiveSearch") || 
336             CmiGetArgFlag(argv,"+CPAlwaysUseDefaults") || 
337             CmiGetArgFlag(argv,"+CPSimulAnneal") || 
338             CmiGetArgFlag(argv,"+CPCriticalPathPrio") || 
339             CmiGetArgFlag(argv,"+CPBestKnown") || 
340             CmiGetArgFlag(argv,"+CPSteering") || 
341             CmiGetArgFlag(argv,"+CPMemoryAware") || 
342             CmiGetArgFlag(argv,"+CPSimplex") || 
343             CmiGetArgFlag(argv,"+CPDivideConquer") || 
344             CmiGetArgFlag(argv,"+CPLDBPeriod") || 
345             CmiGetArgFlag(argv,"+CPLDBPeriodLinear") || 
346             CmiGetArgFlag(argv,"+CPLDBPeriodQuadratic") || 
347             CmiGetArgFlag(argv,"+CPLDBPeriodOptimal") || 
348             CmiGetArgFlag(argv,"+CPDefaultValues") || 
349             CmiGetArgFlag(argv,"+CPGatherAll") || 
350             CmiGetArgFlag(argv,"+CPGatherMemoryUsage") || 
351             CmiGetArgFlag(argv,"+CPGatherUtilization") || 
352             CmiGetArgFlag(argv,"+CPSaveData") || 
353             CmiGetArgFlag(argv,"+CPNoFilterData") || 
354             CmiGetArgFlag(argv,"+CPLoadData") || 
355             CmiGetArgFlag(argv,"+CPDataFilename")    )
356           {         
357             CkAbort("You specified a control point command line argument, but compiled charm++ without control point support.\n");
358           }
359 #endif
360        
361 }
362
363 static void _bufferHandler(void *msg)
364 {
365   DEBUGF(("[%d] _bufferHandler called.\n", CkMyPe()));
366   CkpvAccess(_buffQ)->enq(msg);
367 }
368
369 static void _discardHandler(envelope *env)
370 {
371 //  MESSAGE_PHASE_CHECK(env);
372
373   DEBUGF(("[%d] _discardHandler called.\n", CkMyPe()));
374 #if CMK_MEM_CHECKPOINT
375   CkPrintf("[%d] _discardHandler called!\n", CkMyPe());
376   if (CkInRestarting()) CpvAccess(_qd)->process();
377 #endif
378   CmiFree(env);
379 }
380
381 #if CMK_WITH_STATS
382 static inline void _printStats(void)
383 {
384   DEBUGF(("[%d] _printStats\n", CkMyPe()));
385   int i;
386   if(_printSS || _printCS) {
387     Stats *total = new Stats();
388     _MEMCHECK(total);
389     for(i=0;i<CkNumPes();i++)
390       total->combine(_allStats[i]);
391     CkPrintf("Charm Kernel Summary Statistics:\n");
392     for(i=0;i<CkNumPes();i++) {
393       CkPrintf("Proc %d: [%d created, %d processed]\n", i,
394                _allStats[i]->getCharesCreated(),
395                _allStats[i]->getCharesProcessed());
396     }
397     CkPrintf("Total Chares: [%d created, %d processed]\n",
398              total->getCharesCreated(), total->getCharesProcessed());
399   }
400   if(_printCS) {
401     CkPrintf("Charm Kernel Detailed Statistics (R=requested P=processed):\n\n");
402
403     CkPrintf("         Create    Mesgs     Create    Mesgs     Create    Mesgs\n");
404     CkPrintf("         Chare     for       Group     for       Nodegroup for\n");
405     CkPrintf("PE   R/P Mesgs     Chares    Mesgs     Groups    Mesgs     Nodegroups\n");
406     CkPrintf("---- --- --------- --------- --------- --------- --------- ----------\n");
407
408     for(i=0;i<CkNumPes();i++) {
409       CkPrintf("%4d  R  %9d %9d %9d %9d %9d %9d\n      P  %9d %9d %9d %9d %9d %9d\n",i,
410                _allStats[i]->getCharesCreated(),
411                _allStats[i]->getForCharesCreated(),
412                _allStats[i]->getGroupsCreated(),
413                _allStats[i]->getGroupMsgsCreated(),
414                _allStats[i]->getNodeGroupsCreated(),
415                _allStats[i]->getNodeGroupMsgsCreated(),
416                _allStats[i]->getCharesProcessed(),
417                _allStats[i]->getForCharesProcessed(),
418                _allStats[i]->getGroupsProcessed(),
419                _allStats[i]->getGroupMsgsProcessed(),
420                _allStats[i]->getNodeGroupsProcessed(),
421                _allStats[i]->getNodeGroupMsgsProcessed());
422     }
423   }
424 }
425 #else
426 static inline void _printStats(void) {}
427 #endif
428
429 static inline void _sendStats(void)
430 {
431   DEBUGF(("[%d] _sendStats\n", CkMyPe()));
432 #if CMK_WITH_STATS
433   envelope *env = UsrToEnv(CkpvAccess(_myStats));
434 #else
435   envelope *env = _allocEnv(StatMsg);
436 #endif
437   env->setSrcPe(CkMyPe());
438   CmiSetHandler(env, _exitHandlerIdx);
439   CmiSyncSendAndFree(0, env->getTotalsize(), (char *)env);
440 }
441
442 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
443 extern void _messageLoggingExit();
444 #endif
445
446 #if __FAULT__
447 //CpvExtern(int, CldHandlerIndex);
448 //extern "C" void CldHandler(char *);
449 extern int index_skipCldHandler;
450 extern void _skipCldHandler(void *converseMsg);
451
452 void _discard_charm_message()
453 {
454   CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
455 //  CkNumberHandler(CpvAccess(CldHandlerIndex), (CmiHandler)_discardHandler);
456   CkNumberHandler(index_skipCldHandler, (CmiHandler)_discardHandler);
457 }
458
459 void _resume_charm_message()
460 {
461   CkNumberHandlerEx(_charmHandlerIdx,(CmiHandlerEx)_processHandler,
462         CkpvAccess(_coreState));
463 //  CkNumberHandler(CpvAccess(CldHandlerIndex), (CmiHandler)CldHandler);
464   CkNumberHandler(index_skipCldHandler, (CmiHandler)_skipCldHandler);
465 }
466 #endif
467
468 static void _exitHandler(envelope *env)
469 {
470   DEBUGF(("exitHandler called on %d msgtype: %d\n", CkMyPe(), env->getMsgtype()));
471   switch(env->getMsgtype()) {
472     case StartExitMsg:
473       CkAssert(CkMyPe()==0);
474       if(!CharmLibInterOperate) {
475         if (!_CkExitFnVec.isEmpty()) {
476           CkExitFn fn = _CkExitFnVec.deq();
477           fn();
478           break;
479         }
480       }
481       // else goto next
482     case ExitMsg:
483       CkAssert(CkMyPe()==0);
484       if(_exitStarted) {
485         CmiFree(env);
486         return;
487       }
488       _exitStarted = 1;
489       if(!CharmLibInterOperate) {
490         CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
491         CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
492       }
493       env->setMsgtype(ReqStatMsg);
494       env->setSrcPe(CkMyPe());
495       // if exit in ring, instead of broadcasting, send in ring
496       if (_ringexit){
497         DEBUGF(("[%d] Ring Exit \n",CkMyPe()));
498         const int stride = CkNumPes()/_ringtoken;
499         int pe = 0;
500         while (pe<CkNumPes()) {
501           CmiSyncSend(pe, env->getTotalsize(), (char *)env);
502           pe += stride;
503         }
504         CmiFree(env);
505       }else{
506         CmiSyncBroadcastAllAndFree(env->getTotalsize(), (char *)env);
507       } 
508       break;
509     case ReqStatMsg:
510     if(!CharmLibInterOperate) {
511 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
512         _messageLoggingExit();
513 #endif
514       DEBUGF(("ReqStatMsg on %d\n", CkMyPe()));
515       CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
516       CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
517       /*FAULT_EVAC*/
518       if(CmiNodeAlive(CkMyPe())){
519          _sendStats();
520       }
521       _mainDone = 1; // This is needed because the destructors for
522                      // readonly variables will be called when the program
523                      // exits. If the destructor is called while _mainDone
524                      // is 0, it will assume that the readonly variable was
525                      // declared locally. On all processors other than 0, 
526                      // _mainDone is never set to 1 before the program exits.
527 #if CMK_TRACE_ENABLED
528       if (_ringexit) traceClose();
529 #endif
530     }
531       if (_ringexit) {
532         int stride = CkNumPes()/_ringtoken;
533         int pe = CkMyPe()+1;
534         if (pe < CkNumPes() && pe % stride != 0)
535           CmiSyncSendAndFree(pe, env->getTotalsize(), (char *)env);
536         else
537           CmiFree(env);
538       }
539       else
540         CmiFree(env);
541       //everyone exits here - there may be issues with leftover messages in the queue
542       if(CharmLibInterOperate) {
543         DEBUGF(("[%d] Calling converse exit \n",CkMyPe()));
544         _exitStarted = 0;
545         CpvAccess(charmLibExitFlag) = 1;
546       } else {
547         if(CkMyPe()){
548           DEBUGF(("[%d] Calling converse exit \n",CkMyPe()));
549           CharmLibInterOperate = storeInterOperateStatus;
550           CpvAccess(charmLibExitFlag) = 1;
551           ConverseExit();
552         }
553       }
554       break;
555     case StatMsg:
556 // shouldn't reach here in interoperate mode
557       CkAssert(CkMyPe()==0);
558 #if CMK_WITH_STATS
559       _allStats[env->getSrcPe()] = (Stats*) EnvToUsr(env);
560 #endif
561       _numStatsRecd++;
562       DEBUGF(("StatMsg on %d with %d\n", CkMyPe(), _numStatsRecd));
563                         /*FAULT_EVAC*/
564       if(_numStatsRecd==CkNumValidPes()) {
565         _printStats();
566         DEBUGF(("[%d] Calling converse exit \n",CkMyPe()));
567         CharmLibInterOperate = storeInterOperateStatus;
568         CpvAccess(charmLibExitFlag) = 1;
569         ConverseExit();
570       }
571       break;
572     default:
573       CmiAbort("Internal Error(_exitHandler): Unknown-msg-type. Contact Developers.\n");
574   }
575 }
576
577 /**
578  * Create all groups in this processor (not called on processor zero).
579  * Notice that only groups created in mainchares are processed here;
580  * groups created later are processed as regular messages.
581  */
582 static inline void _processBufferedBocInits(void)
583 {
584   CkCoreState *ck = CkpvAccess(_coreState);
585   CkNumberHandlerEx(_bocHandlerIdx,(CmiHandlerEx)_processHandler, ck);
586   register int i = 0;
587   PtrVec &inits=*CkpvAccess(_bocInitVec);
588   register int len = inits.size();
589   for(i=1; i<len; i++) {
590     envelope *env = inits[i];
591     if(env==0) CkAbort("_processBufferedBocInits: empty message");
592     if(env->isPacked())
593       CkUnpackMessage(&env);
594     _processBocInitMsg(ck,env);
595   }
596   delete &inits;
597 }
598
599 /**
600  * Create all nodegroups in this node (called only by rank zero, and never on node zero).
601  * Notice that only nodegroups created in mainchares are processed here;
602  * nodegroups created later are processed as regular messages.
603  */
604 static inline void _processBufferedNodeBocInits(void)
605 {
606   CkCoreState *ck = CkpvAccess(_coreState);
607   register int i = 0;
608   PtrVec &inits=*CksvAccess(_nodeBocInitVec);
609   register int len = inits.size();
610   for(i=1; i<len; i++) {
611     envelope *env = inits[i];
612     if(env==0) CkAbort("_processBufferedNodeBocInits: empty message");
613     if(env->isPacked())
614       CkUnpackMessage(&env);
615     _processNodeBocInitMsg(ck,env);
616   }
617   delete &inits;
618 }
619
620 static inline void _processBufferedMsgs(void)
621 {
622   CkNumberHandlerEx(_charmHandlerIdx,(CmiHandlerEx)_processHandler,
623         CkpvAccess(_coreState));
624   envelope *env;
625   while(NULL!=(env=(envelope*)CkpvAccess(_buffQ)->deq())) {
626     if(env->getMsgtype()==NewChareMsg || env->getMsgtype()==NewVChareMsg) {
627       if(env->isForAnyPE())
628         _CldEnqueue(CLD_ANYWHERE, env, _infoIdx);
629       else
630         _processHandler((void *)env, CkpvAccess(_coreState));
631     } else {
632       _processHandler((void *)env, CkpvAccess(_coreState));
633     }
634   }
635 }
636
637 static int _charmLoadEstimator(void)
638 {
639   return CkpvAccess(_buffQ)->length();
640 }
641
642 /**
643  * This function is used to send other processors on the same node a signal so
644  * they can check if their _initDone can be called: the reason for this is that
645  * the check at the end of _initHandler can fail due to a missing message containing
646  * a Nodegroup creation. When that message arrives only one processor will receive
647  * it, and thus if no notification is sent to the other processors in the node, they
648  * will never proceed.
649  */
650 static void _sendTriggers(void)
651 {
652   int i, num, first;
653   CmiImmediateLock(CksvAccess(_nodeGroupTableImmLock));
654   if (CksvAccess(_triggersSent) == 0)
655   {
656     CksvAccess(_triggersSent)++;
657     num = CmiMyNodeSize();
658     register envelope *env = _allocEnv(RODataMsg); // Notice that the type here is irrelevant
659     env->setSrcPe(CkMyPe());
660     CmiSetHandler(env, _triggerHandlerIdx);
661     first = CmiNodeFirst(CmiMyNode());
662     for (i=0; i < num; i++)
663       if(first+i != CkMyPe())
664         CmiSyncSend(first+i, env->getTotalsize(), (char *)env);
665     CmiFree(env);
666   }
667   CmiImmediateUnlock(CksvAccess(_nodeGroupTableImmLock));
668 }
669
670 /**
671  * This function (not a handler) is called once and only once per processor.
672  * It signals the processor that the initialization is done and regular messages
673  * can be processed.
674  *
675  * On processor zero it is called by _initCharm, on all other processors either
676  * by _initHandler or _triggerHandler (cannot be both).
677  * When fault-tolerance is active, it is called by the fault-tolerance scheme itself.
678  */
679 void _initDone(void)
680 {
681   DEBUGF(("[%d] _initDone.\n", CkMyPe()));
682   if (!CksvAccess(_triggersSent)) _sendTriggers();
683   CkNumberHandler(_triggerHandlerIdx, (CmiHandler)_discardHandler);
684   CmiNodeBarrier();
685   if(CkMyRank() == 0) {
686     _processBufferedNodeBocInits();
687   }
688   CmiNodeBarrier(); // wait for all nodegroups to be created
689   _processBufferedBocInits();
690   DEBUGF(("Reached CmiNodeBarrier(), pe = %d, rank = %d\n", CkMyPe(), CkMyRank()));
691   CmiNodeBarrier();
692   DEBUGF(("Crossed CmiNodeBarrier(), pe = %d, rank = %d\n", CkMyPe(), CkMyRank()));
693   _processBufferedMsgs();
694   CkpvAccess(_charmEpoch)=1;
695 }
696
697 /**
698  * Converse handler receiving a signal from another processors in the same node.
699  * (On _sendTrigger there is the explanation of why this is necessary)
700  * Simply check if with the NodeGroup processed by another processor we reached
701  * the expected count. Notice that it can only be called before _initDone: after
702  * _initDone, a message destined for this handler will go instead to the _discardHandler.
703  */
704 static void _triggerHandler(envelope *env)
705 {
706   if (_numExpectInitMsgs && CkpvAccess(_numInitsRecd) + CksvAccess(_numInitNodeMsgs) == _numExpectInitMsgs)
707   {
708     DEBUGF(("Calling Init Done from _triggerHandler\n"));
709     _initDone();
710   }
711   CmiFree(env);
712 }
713
714 static inline void _processROMsgMsg(envelope *env)
715 {
716   *((char **)(_readonlyMsgs[env->getRoIdx()]->pMsg))=(char *)EnvToUsr(env);
717 }
718
719 static inline void _processRODataMsg(envelope *env)
720 {
721   //Unpack each readonly:
722   PUP::fromMem pu((char *)EnvToUsr(env));
723   for(size_t i=0;i<_readonlyTable.size();i++) _readonlyTable[i]->pupData(pu);
724   CmiFree(env);
725 }
726
727 /**
728  * This is similar to the _initHandler, only that the Groups and Nodegroups are
729  * initialized from disk, so only one single message is expected.
730  *
731  * It is unclear how Readonly Messages are treated during restart... (if at all considered)
732  */
733 static void _roRestartHandler(void *msg)
734 {
735   CkAssert(CkMyPe()!=0);
736   register envelope *env = (envelope *) msg;
737   CkpvAccess(_numInitsRecd)++;
738   _numExpectInitMsgs = env->getCount();
739   _processRODataMsg(env);
740 }
741
742 /**
743  * This handler is used only during initialization. It receives messages from
744  * processor zero regarding Readonly Data (in one single message), Readonly Messages,
745  * Groups, and Nodegroups.
746  * The Readonly Data message also contains the total number of messages expected
747  * during the initialization phase.
748  * For Groups and Nodegroups, only messages with epoch=0 (meaning created from within
749  * a mainchare) are buffered for special creation, the other messages are buffered
750  * together with all the other regular messages by _bufferHandler (and will be flushed
751  * after all the initialization messages have been processed).
752  */
753 static void _initHandler(void *msg, CkCoreState *ck)
754 {
755   CkAssert(CkMyPe()!=0);
756   register envelope *env = (envelope *) msg;
757   
758   if (ck->watcher!=NULL) {
759     if (!ck->watcher->processMessage(&env,ck)) return;
760   }
761   
762   switch (env->getMsgtype()) {
763     case BocInitMsg:
764       if (env->getGroupEpoch()==0) {
765         CkpvAccess(_numInitsRecd)++;
766         // _processBocInitMsg already handles QD
767         //CpvAccess(_qd)->process();
768         CkpvAccess(_bocInitVec)->insert(env->getGroupNum().idx, env);
769       } else _bufferHandler(msg);
770       break;
771     case NodeBocInitMsg:
772       if (env->getGroupEpoch()==0) {
773         CmiImmediateLock(CksvAccess(_nodeGroupTableImmLock));
774         CksvAccess(_numInitNodeMsgs)++;
775         CksvAccess(_nodeBocInitVec)->insert(env->getGroupNum().idx, env);
776         CmiImmediateUnlock(CksvAccess(_nodeGroupTableImmLock));
777         CpvAccess(_qd)->process();
778       } else _bufferHandler(msg);
779       break;
780     case ROMsgMsg:
781       CkpvAccess(_numInitsRecd)++;
782       CpvAccess(_qd)->process();
783       if(env->isPacked()) CkUnpackMessage(&env);
784       _processROMsgMsg(env);
785       break;
786     case RODataMsg:
787       CkpvAccess(_numInitsRecd)++;
788       CpvAccess(_qd)->process();
789       _numExpectInitMsgs = env->getCount();
790       _processRODataMsg(env);
791       break;
792     default:
793       CmiAbort("Internal Error: Unknown-msg-type. Contact Developers.\n");
794   }
795         DEBUGF(("[%d,%.6lf] _numExpectInitMsgs %d CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs) %d+%d\n",CmiMyPe(),CmiWallTimer(),_numExpectInitMsgs,CkpvAccess(_numInitsRecd),CksvAccess(_numInitNodeMsgs)));
796   if(_numExpectInitMsgs&&(CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs)==_numExpectInitMsgs)) {
797     _initDone();
798   }
799 }
800
801 #if 0
802 /*****************************************
803  *          no longer needed
804  * ***************************************/
805 extern "C"
806 void _CkExit(void) 
807 {
808   CmiAssert(CkMyPe() == 0);
809   // Shuts down Converse handlers for the upper layers on this processor
810   //
811   CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
812   CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
813   DEBUGF(("[%d] CkExit - _exitStarted:%d %d\n", CkMyPe(), _exitStarted, _exitHandlerIdx));
814
815   if(CkMyPe()==0) {
816     if(_exitStarted)
817       CsdScheduler(-1);
818     envelope *env = _allocEnv(ReqStatMsg);
819     env->setSrcPe(CkMyPe());
820     CmiSetHandler(env, _exitHandlerIdx);
821                 /*FAULT_EVAC*/
822     CmiSyncBroadcastAllAndFree(env->getTotalsize(), (char *)env);
823   } else {
824     envelope *env = _allocEnv(ExitMsg);
825     env->setSrcPe(CkMyPe());
826     CmiSetHandler(env, _exitHandlerIdx);
827     CmiSyncSendAndFree(0, env->getTotalsize(), (char *)env);
828   }
829 #if ! CMK_BIGSIM_THREAD
830   _TRACE_END_EXECUTE();
831   //Wait for stats, which will call ConverseExit when finished:
832   CsdScheduler(-1);
833 #endif
834 }
835 #endif
836
837 CkQ<CkExitFn> _CkExitFnVec;
838
839 // triger exit on PE 0,
840 // which traverses _CkExitFnVec to call every registered user exit functions.
841 // Every user exit functions should end with CkExit() to continue the chain
842 extern "C"
843 void CkExit(void)
844 {
845         /*FAULT_EVAC*/
846   DEBUGF(("[%d] CkExit called \n",CkMyPe()));
847     // always send to PE 0
848   envelope *env = _allocEnv(StartExitMsg);
849   env->setSrcPe(CkMyPe());
850   CmiSetHandler(env, _exitHandlerIdx);
851   CmiSyncSendAndFree(0, env->getTotalsize(), (char *)env);
852
853   if(!CharmLibInterOperate) {
854 #if ! CMK_BIGSIM_THREAD
855     _TRACE_END_EXECUTE();
856     //Wait for stats, which will call ConverseExit when finished:
857     if(!storeInterOperateStatus)
858       CsdScheduler(-1);
859 #endif
860   }
861 }
862
863 /* This is a routine called in case the application is closing due to a signal.
864    Tear down structures that must be cleaned up even when unclean exit happens.
865    It is called by the machine layer whenever some problem occurs (it is thus up
866    to the machine layer to call this function). */
867 extern "C"
868 void EmergencyExit(void) {
869 #ifndef __BIGSIM__
870   /* Delete _coreState to force any CkMessageWatcher to close down. */
871   if (CkpvAccess(_coreState) != NULL) {
872     delete CkpvAccess(_coreState);
873     CkpvAccess(_coreState) = NULL;
874   }
875 #endif
876 }
877
878 static void _nullFn(void *, void *)
879 {
880   CmiAbort("Null-Method Called. Program may have Unregistered Module!!\n");
881 }
882
883 extern void _registerLBDatabase(void);
884 extern void _registerPathHistory(void);
885 #if CMK_WITH_CONTROLPOINT
886 extern void _registerControlPoints(void);
887 #endif
888 extern void _registerTraceControlPoints();
889 extern void _registerExternalModules(char **argv);
890 extern void _ckModuleInit(void);
891 extern void _loadbalancerInit();
892 extern void _initChareTables();
893 #if CMK_MEM_CHECKPOINT
894 extern void init_memcheckpt(char **argv);
895 #endif
896 extern "C" void initCharmProjections();
897 extern "C" void CmiInitCPUTopology(char **argv);
898 extern "C" void CmiInitCPUAffinity(char **argv);
899 extern "C" void CmiInitMemAffinity(char **argv);
900 extern "C" void CmiInitPxshm(char **argv);
901
902 //extern "C" void CldCallback();
903
904 void _registerInitCall(CkInitCallFn fn, int isNodeCall)
905 {
906   if (isNodeCall) _initCallTable.initNodeCalls.enq(fn);
907   else _initCallTable.initProcCalls.enq(fn);
908 }
909
910 void InitCallTable::enumerateInitCalls()
911 {
912   int i;
913 #ifdef __BIGSIM__
914   if(BgNodeRank()==0)        // called only once on an emulating node
915 #else
916   if(CkMyRank()==0) 
917 #endif
918   {
919     for (i=0; i<initNodeCalls.length(); i++) initNodeCalls[i]();
920   }
921   // initproc may depend on initnode calls.
922   CmiNodeAllBarrier();
923   for (i=0; i<initProcCalls.length(); i++) initProcCalls[i]();
924 }
925
926 CpvCExtern(int, cpdSuspendStartup);
927 extern "C" void CpdFreeze(void);
928
929 extern int _dummy_dq;
930
931 extern "C" void initQd(char **argv)
932 {
933         CpvInitialize(QdState*, _qd);
934         CpvAccess(_qd) = new QdState();
935         if (CmiMyRank() == 0) {
936 #if !defined(CMK_CPV_IS_SMP) && !CMK_SHARED_VARS_UNIPROCESSOR
937         CpvAccessOther(_qd, 1) = new QdState(); // for i/o interrupt
938 #endif
939         }
940         _qdHandlerIdx = CmiRegisterHandler((CmiHandler)_qdHandler);
941         _qdCommHandlerIdx = CmiRegisterHandler((CmiHandler)_qdCommHandler);
942         if (CmiGetArgIntDesc(argv,"+qd",&_dummy_dq, "QD time in seconds")) {
943           if (CmiMyPe()==0)
944             CmiPrintf("Charm++> Fake QD using %d seconds.\n", _dummy_dq);
945         }
946 }
947
948 #if CMK_BIGSIM_CHARM && CMK_CHARMDEBUG
949 void CpdBgInit();
950 #endif
951 void CpdBreakPointInit();
952
953 /**
954   This is the main charm setup routine.  It's called
955   on all processors after Converse initialization.
956   This routine gets passed to Converse from "main.C".
957   
958   The main purpose of this routine is to set up the objects
959   and Ckpv's used during a regular Charm run.  See the comment
960   at the top of the file for overall flow.
961 */
962 void _initCharm(int unused_argc, char **argv)
963
964         int inCommThread = (CmiMyRank() == CmiMyNodeSize());
965
966         if(CmiMyNode() == 0 && CmiMyRank() == 0) {
967     if(CmiGetArgFlag(argv, "+printTopo")) {
968                         TopoManager tmgr;
969                         tmgr.printAllocation();
970                 }
971         }
972
973         DEBUGF(("[%d,%.6lf ] _initCharm started\n",CmiMyPe(),CmiWallTimer()));
974
975         CkpvInitialize(size_t *, _offsets);
976         CkpvAccess(_offsets) = new size_t[32];
977         CkpvInitialize(PtrQ*,_buffQ);
978         CkpvInitialize(PtrVec*,_bocInitVec);
979         CkpvInitialize(void*, _currentChare);
980         CkpvInitialize(int,   _currentChareType);
981         CkpvInitialize(CkGroupID, _currentGroup);
982         CkpvInitialize(void *, _currentNodeGroupObj);
983         CkpvInitialize(CkGroupID, _currentGroupRednMgr);
984         CkpvInitialize(GroupTable*, _groupTable);
985         CkpvInitialize(GroupIDTable*, _groupIDTable);
986         CkpvInitialize(CmiImmediateLockType, _groupTableImmLock);
987         CkpvInitialize(UInt, _numGroups);
988         CkpvInitialize(int, _numInitsRecd);
989         CkpvInitialize(char**, Ck_argv); CkpvAccess(Ck_argv)=argv;
990         CkpvInitialize(MsgPool*, _msgPool);
991         CkpvInitialize(CkCoreState *, _coreState);
992         /*
993                 Added for evacuation-sayantan
994         */
995 #ifndef __BIGSIM__
996         CpvInitialize(char *,_validProcessors);
997 #endif
998         CkpvInitialize(char ,startedEvac);
999         CpvInitialize(int,serializer);
1000
1001         _initChareTables();            // for checkpointable plain chares
1002
1003         CksvInitialize(UInt, _numNodeGroups);
1004         CksvInitialize(GroupTable*, _nodeGroupTable);
1005         CksvInitialize(GroupIDTable, _nodeGroupIDTable);
1006         CksvInitialize(CmiImmediateLockType, _nodeGroupTableImmLock);
1007         CksvInitialize(CmiNodeLock, _nodeLock);
1008         CksvInitialize(PtrVec*,_nodeBocInitVec);
1009         CksvInitialize(UInt,_numInitNodeMsgs);
1010         CkpvInitialize(int,_charmEpoch);
1011         CkpvAccess(_charmEpoch)=0;
1012         CksvInitialize(int, _triggersSent);
1013         CksvAccess(_triggersSent) = 0;
1014
1015         CkpvInitialize(_CkOutStream*, _ckout);
1016         CkpvInitialize(_CkErrStream*, _ckerr);
1017         CkpvInitialize(Stats*, _myStats);
1018
1019         CkpvAccess(_groupIDTable) = new GroupIDTable(0);
1020         CkpvAccess(_groupTable) = new GroupTable;
1021         CkpvAccess(_groupTable)->init();
1022         CkpvAccess(_groupTableImmLock) = CmiCreateImmediateLock();
1023         CkpvAccess(_numGroups) = 1; // make 0 an invalid group number
1024         CkpvAccess(_buffQ) = new PtrQ();
1025         CkpvAccess(_bocInitVec) = new PtrVec();
1026
1027         CkpvAccess(_currentNodeGroupObj) = NULL;
1028
1029         if(CkMyRank()==0)
1030         {
1031                 CksvAccess(_numNodeGroups) = 1; //make 0 an invalid group number
1032                 CksvAccess(_numInitNodeMsgs) = 0;
1033                 CksvAccess(_nodeLock) = CmiCreateLock();
1034                 CksvAccess(_nodeGroupTable) = new GroupTable();
1035                 CksvAccess(_nodeGroupTable)->init();
1036                 CksvAccess(_nodeGroupTableImmLock) = CmiCreateImmediateLock();
1037                 CksvAccess(_nodeBocInitVec) = new PtrVec();
1038         }
1039
1040         CkCallbackInit();
1041         
1042         CmiNodeAllBarrier();
1043
1044 #if ! CMK_BIGSIM_CHARM
1045         initQd(argv);         // bigsim calls it in ConverseCommonInit
1046 #endif
1047
1048         CkpvAccess(_coreState)=new CkCoreState();
1049
1050         CkpvAccess(_numInitsRecd) = 0;
1051
1052         CkpvAccess(_ckout) = new _CkOutStream();
1053         CkpvAccess(_ckerr) = new _CkErrStream();
1054
1055         _charmHandlerIdx = CkRegisterHandler((CmiHandler)_bufferHandler);
1056         _initHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
1057         CkNumberHandlerEx(_initHandlerIdx, (CmiHandlerEx)_initHandler, CkpvAccess(_coreState));
1058         _roRestartHandlerIdx = CkRegisterHandler((CmiHandler)_roRestartHandler);
1059         _exitHandlerIdx = CkRegisterHandler((CmiHandler)_exitHandler);
1060         _bocHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
1061         CkNumberHandlerEx(_bocHandlerIdx, (CmiHandlerEx)_initHandler, CkpvAccess(_coreState));
1062
1063 #ifdef __BIGSIM__
1064         if(BgNodeRank()==0) 
1065 #endif
1066         _infoIdx = CldRegisterInfoFn((CldInfoFn)_infoFn);
1067
1068         _triggerHandlerIdx = CkRegisterHandler((CmiHandler)_triggerHandler);
1069         _ckModuleInit();
1070
1071         CldRegisterEstimator((CldEstimator)_charmLoadEstimator);
1072
1073         _futuresModuleInit(); // part of futures implementation is a converse module
1074         _loadbalancerInit();
1075         
1076 #if CMK_MEM_CHECKPOINT
1077         init_memcheckpt(argv);
1078 #endif
1079
1080         initCharmProjections();
1081 #if CMK_TRACE_IN_CHARM
1082         // initialize trace module in ck
1083         traceCharmInit(argv);
1084 #endif
1085         
1086     CkpvInitialize(int, envelopeEventID);
1087     CkpvAccess(envelopeEventID) = 0;
1088         CkMessageWatcherInit(argv,CkpvAccess(_coreState));
1089         
1090         /**
1091           The rank-0 processor of each node calls the 
1092           translator-generated "_register" routines. 
1093           
1094           _register routines call the charm.h "CkRegister*" routines,
1095           which record function pointers and class information for
1096           all Charm entities, like Chares, Arrays, and readonlies.
1097           
1098           There's one _register routine generated for each
1099           .ci file.  _register routines *must* be called in the 
1100           same order on every node, and *must not* be called by 
1101           multiple threads simultaniously.
1102         */
1103 #ifdef __BIGSIM__
1104         if(BgNodeRank()==0) 
1105 #else
1106         if(CkMyRank()==0)
1107 #endif
1108         {
1109                 CmiArgGroup("Charm++",NULL);
1110                 _parseCommandLineOpts(argv);
1111                 _registerInit();
1112                 CkRegisterMsg("System", 0, 0, CkFreeMsg, sizeof(int));
1113                 CkRegisterChareInCharm(CkRegisterChare("null", 0, TypeChare));
1114                 CkIndex_Chare::__idx=CkRegisterChare("Chare", sizeof(Chare), TypeChare);
1115                 CkRegisterChareInCharm(CkIndex_Chare::__idx);
1116                 CkIndex_Group::__idx=CkRegisterChare("Group", sizeof(Group), TypeGroup);
1117                 CkRegisterChareInCharm(CkIndex_Group::__idx);
1118                 CkRegisterEp("null", (CkCallFnPtr)_nullFn, 0, 0, 0+CK_EP_INTRINSIC);
1119                 
1120                 /**
1121                   These _register calls are for the built-in
1122                   Charm .ci files, like arrays and load balancing.
1123                   If you add a .ci file to charm, you'll have to 
1124                   add a call to the _register routine here, or make
1125                   your library into a "-module".
1126                 */
1127                 _registerCkFutures();
1128                 _registerCkArray();
1129                 _registerLBDatabase();
1130                 _registerCkCallback();
1131                 _registertempo();
1132                 _registerwaitqd();
1133                 _registercharisma();
1134                 _registerCkCheckpoint();
1135 #if CMK_MEM_CHECKPOINT
1136                 _registerCkMemCheckpoint();
1137 #endif
1138
1139
1140                 /*
1141                   Setup Control Point Automatic Tuning Framework.
1142
1143                   By default it is enabled as a part of charm, 
1144                   however it won't enable its tracing module 
1145                   unless a +CPEnableMeasurements command line argument
1146                   is specified. See trace-common.C for more info
1147
1148                   Thus there should be no noticable overhead to 
1149                   always having the control point framework linked
1150                   in.
1151                   
1152                 */
1153 #if CMK_WITH_CONTROLPOINT
1154                 _registerPathHistory();
1155                 _registerControlPoints();
1156                 _registerTraceControlPoints();
1157 #endif
1158
1159
1160                 /**
1161                   CkRegisterMainModule is generated by the (unique)
1162                   "mainmodule" .ci file.  It will include calls to 
1163                   register all the .ci files.
1164                 */
1165                 CkRegisterMainModule();
1166
1167                 /**
1168                   _registerExternalModules is actually generated by 
1169                   charmc at link time (as "moduleinit<pid>.C").  
1170                   
1171                   This generated routine calls the _register functions
1172                   for the .ci files of libraries linked using "-module".
1173                   This funny initialization is most useful for AMPI/FEM
1174                   programs, which don't have a .ci file and hence have
1175                   no other way to control the _register process.
1176                 */
1177                 _registerExternalModules(argv);
1178                 
1179                 _registerDone();
1180         }
1181         /* The following will happen on every virtual processor in BigEmulator, not just on once per real processor */
1182         if (CkMyRank() == 0) {
1183           CpdBreakPointInit();
1184         }
1185         CmiNodeAllBarrier();
1186
1187         // Execute the initcalls registered in modules
1188         _initCallTable.enumerateInitCalls();
1189
1190 #if CMK_CHARMDEBUG
1191         CpdFinishInitialization();
1192 #endif
1193
1194         //CmiNodeAllBarrier();
1195
1196         CkpvAccess(_myStats) = new Stats();
1197         CkpvAccess(_msgPool) = new MsgPool();
1198
1199         CmiNodeAllBarrier();
1200
1201 #if ! CMK_MEM_CHECKPOINT
1202         CmiBarrier();
1203         CmiBarrier();
1204         CmiBarrier();
1205 #endif
1206 #if CMK_SMP_TRACE_COMMTHREAD
1207         _TRACE_BEGIN_COMPUTATION();     
1208 #else
1209         if (!inCommThread) {
1210           _TRACE_BEGIN_COMPUTATION();
1211         }
1212 #endif
1213
1214 #ifdef ADAPT_SCHED_MEM
1215     if(CkMyRank()==0){
1216         memCriticalEntries = new int[numMemCriticalEntries];
1217         int memcnt=0;
1218         for(int i=0; i<_entryTable.size(); i++){
1219             if(_entryTable[i]->isMemCritical){
1220                 memCriticalEntries[memcnt++] = i;
1221             }
1222         }
1223     }
1224 #endif
1225
1226 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
1227     _messageLoggingInit();
1228 #endif
1229
1230 #ifndef __BIGSIM__
1231         /*
1232                 FAULT_EVAC
1233         */
1234         CpvAccess(_validProcessors) = new char[CkNumPes()];
1235         for(int vProc=0;vProc<CkNumPes();vProc++){
1236                 CpvAccess(_validProcessors)[vProc]=1;
1237         }
1238         _ckEvacBcastIdx = CkRegisterHandler((CmiHandler)_ckEvacBcast);
1239         _ckAckEvacIdx = CkRegisterHandler((CmiHandler)_ckAckEvac);
1240 #endif
1241         CkpvAccess(startedEvac) = 0;
1242         CpvAccess(serializer) = 0;
1243
1244         evacuate = 0;
1245         CcdCallOnCondition(CcdSIGUSR1,(CcdVoidFn)CkDecideEvacPe,0);
1246 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_)) 
1247     CcdCallOnCondition(CcdSIGUSR2,(CcdVoidFn)CkMlogRestart,0);
1248 #endif
1249
1250         if(_raiseEvac){
1251                 processRaiseEvacFile(_raiseEvacFile);
1252                 /*
1253                 if(CkMyPe() == 2){
1254                 //      CcdCallOnConditionKeep(CcdPERIODIC_10s,(CcdVoidFn)CkDecideEvacPe,0);
1255                         CcdCallFnAfter((CcdVoidFn)CkDecideEvacPe, 0, 10000);
1256                 }
1257                 if(CkMyPe() == 3){
1258                         CcdCallFnAfter((CcdVoidFn)CkDecideEvacPe, 0, 10000);
1259                 }*/
1260         }       
1261
1262     if (!_replaySystem) {
1263         if (faultFunc == NULL) {         // this is not restart
1264             // these two are blocking calls for non-bigsim
1265 #if ! CMK_BIGSIM_CHARM
1266           CmiInitCPUAffinity(argv);
1267           CmiInitMemAffinity(argv);
1268 #endif
1269         }
1270         CmiInitCPUTopology(argv);
1271     }
1272
1273 #if CMK_USE_PXSHM && CMK_CRAYXE && CMK_SMP
1274       // for SMP on Cray XE6 (hopper) it seems pxshm has to be initialized
1275       // again after cpuaffinity is done
1276     if (CkMyRank() == 0) {
1277       CmiInitPxshm(argv);
1278     }
1279     CmiNodeAllBarrier();
1280 #endif
1281
1282     //CldCallback();
1283 #if CMK_BIGSIM_CHARM && CMK_CHARMDEBUG
1284       // Register the BG handler for CCS. Notice that this is put into a variable shared by
1285       // the whole real processor. This because converse needs to find it. We check that all
1286       // virtual processors register the same index for this handler.
1287     CpdBgInit();
1288 #endif
1289
1290         if (faultFunc) {
1291 #if CMK_WITH_STATS
1292                 if (CkMyPe()==0) _allStats = new Stats*[CkNumPes()];
1293 #endif
1294                 if (!inCommThread) {
1295                   CkArgMsg *msg = (CkArgMsg *)CkAllocMsg(0, sizeof(CkArgMsg), 0);
1296                   msg->argc = CmiGetArgc(argv);
1297                   msg->argv = argv;
1298                   faultFunc(_restartDir, msg);
1299                   CkFreeMsg(msg);
1300                 }
1301         }else if(CkMyPe()==0){
1302 #if CMK_WITH_STATS
1303                 _allStats = new Stats*[CkNumPes()];
1304 #endif
1305                 register size_t i, nMains=_mainTable.size();
1306                 for(i=0;i<nMains;i++)  /* Create all mainchares */
1307                 {
1308                         register int size = _chareTable[_mainTable[i]->chareIdx]->size;
1309                         register void *obj = malloc(size);
1310                         _MEMCHECK(obj);
1311                         _mainTable[i]->setObj(obj);
1312                         CkpvAccess(_currentChare) = obj;
1313                         CkpvAccess(_currentChareType) = _mainTable[i]->chareIdx;
1314                         register CkArgMsg *msg = (CkArgMsg *)CkAllocMsg(0, sizeof(CkArgMsg), 0);
1315                         msg->argc = CmiGetArgc(argv);
1316                         msg->argv = argv;
1317                         _entryTable[_mainTable[i]->entryIdx]->call(msg, obj);
1318 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
1319             CpvAccess(_currentObj) = (Chare *)obj;
1320 #endif
1321                 }
1322                 _mainDone = 1;
1323
1324                 _STATS_RECORD_CREATE_CHARE_N(nMains);
1325                 _STATS_RECORD_PROCESS_CHARE_N(nMains);
1326
1327
1328
1329
1330                 for(i=0;i<_readonlyMsgs.size();i++) /* Send out readonly messages */
1331                 {
1332                         register void *roMsg = (void *) *((char **)(_readonlyMsgs[i]->pMsg));
1333                         if(roMsg==0)
1334                                 continue;
1335                         //Pack the message and send it to all other processors
1336                         register envelope *env = UsrToEnv(roMsg);
1337                         env->setSrcPe(CkMyPe());
1338                         env->setMsgtype(ROMsgMsg);
1339                         env->setRoIdx(i);
1340                         CmiSetHandler(env, _initHandlerIdx);
1341                         CkPackMessage(&env);
1342                         CmiSyncBroadcast(env->getTotalsize(), (char *)env);
1343                         CpvAccess(_qd)->create(CkNumPes()-1);
1344
1345                         //For processor 0, unpack and re-set the global
1346                         CkUnpackMessage(&env);
1347                         _processROMsgMsg(env);
1348                         _numInitMsgs++;
1349                 }
1350
1351                 //Determine the size of the RODataMessage
1352                 PUP::sizer ps;
1353                 for(i=0;i<_readonlyTable.size();i++) _readonlyTable[i]->pupData(ps);
1354
1355                 //Allocate and fill out the RODataMessage
1356                 envelope *env = _allocEnv(RODataMsg, ps.size());
1357                 PUP::toMem pp((char *)EnvToUsr(env));
1358                 for(i=0;i<_readonlyTable.size();i++) _readonlyTable[i]->pupData(pp);
1359
1360                 env->setCount(++_numInitMsgs);
1361                 env->setSrcPe(CkMyPe());
1362                 CmiSetHandler(env, _initHandlerIdx);
1363                 DEBUGF(("[%d,%.6lf] RODataMsg being sent of size %d \n",CmiMyPe(),CmiWallTimer(),env->getTotalsize()));
1364                 CmiSyncBroadcastAndFree(env->getTotalsize(), (char *)env);
1365                 CpvAccess(_qd)->create(CkNumPes()-1);
1366                 _initDone();
1367         }
1368
1369         DEBUGF(("[%d,%d%.6lf] inCommThread %d\n",CmiMyPe(),CmiMyRank(),CmiWallTimer(),inCommThread));
1370         // when I am a communication thread, I don't participate initDone.
1371         if (inCommThread) {
1372                 CkNumberHandlerEx(_bocHandlerIdx,(CmiHandlerEx)_processHandler,
1373                                         CkpvAccess(_coreState));
1374                 CkNumberHandlerEx(_charmHandlerIdx,(CmiHandlerEx)_processHandler
1375 ,
1376                                         CkpvAccess(_coreState));
1377         }
1378
1379 #if CMK_CHARMDEBUG
1380         // Should not use CpdFreeze inside a thread (since this processor is really a user-level thread)
1381        if (CpvAccess(cpdSuspendStartup))
1382        { 
1383           //CmiPrintf("In Parallel Debugging mode .....\n");
1384           CpdFreeze();
1385        }
1386 #endif
1387
1388
1389 #if __FAULT__
1390         if(killFlag){                                                  
1391                 readKillFile();                                        
1392         }
1393 #endif
1394
1395 }
1396
1397 // this is needed because on o2k, f90 programs have to have main in
1398 // fortran90.
1399 extern "C" void fmain_(int *argc,char _argv[][80],int length[])
1400 {
1401   int i;
1402   char **argv = new char*[*argc+2];
1403
1404   for(i=0;i <= *argc;i++) {
1405     if (length[i] < 100) {
1406       _argv[i][length[i]]='\0';
1407       argv[i] = &(_argv[i][0]);
1408     } else {
1409       argv[i][0] = '\0';
1410     }
1411   }
1412   argv[*argc+1]=0;
1413
1414   ConverseInit(*argc, argv, (CmiStartFn) _initCharm, 0, 0);
1415 }
1416
1417 // user callable function to register an exit function, this function
1418 // will perform task of collecting of info from all pes to pe0, and call
1419 // CkExit() on pe0 again to recursively traverse the registered exitFn.
1420 // see trace-summary for an example.
1421 void registerExitFn(CkExitFn fn)
1422 {
1423   _CkExitFnVec.enq(fn);
1424 }
1425
1426 void CharmLibInit(int peid, int numpes, int argc, char **argv){
1427     //note CmiNumNodes and CmiMyNode should just be macros
1428     _Cmi_numnodes = numpes;
1429     _Cmi_mynode = peid;
1430
1431   CharmLibInterOperate = 1;
1432   ConverseInit(argc, argv, (CmiStartFn)_initCharm, 1, 0);
1433 }
1434
1435 void CharmLibExit() {
1436   storeInterOperateStatus = 1;
1437   CharmLibInterOperate = 0;
1438   if(CkMyPe() == 0) {
1439     CkExit();
1440   }
1441   CsdScheduler(-1);
1442 }
1443 /*@}*/