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