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