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