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