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