Integrated the memory affinity settings into charm++
[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 extern "C" void CmiInitMemAffinity(char **argv);
812
813 void _registerInitCall(CkInitCallFn fn, int isNodeCall)
814 {
815   if (isNodeCall) _initCallTable.initNodeCalls.enq(fn);
816   else _initCallTable.initProcCalls.enq(fn);
817 }
818
819 void InitCallTable::enumerateInitCalls()
820 {
821   int i;
822 #ifdef __BLUEGENE__
823   if(BgNodeRank()==0)        // called only once on an emulating node
824 #else
825   if(CkMyRank()==0) 
826 #endif
827   {
828     for (i=0; i<initNodeCalls.length(); i++) initNodeCalls[i]();
829   }
830   // initproc may depend on initnode calls.
831   CmiNodeAllBarrier();
832   for (i=0; i<initProcCalls.length(); i++) initProcCalls[i]();
833 }
834
835 CpvCExtern(int, cpdSuspendStartup);
836 extern "C" void CpdFreeze(void);
837
838 extern int _dummy_dq;
839
840 extern "C" void initQd(char **argv)
841 {
842         CpvInitialize(QdState*, _qd);
843         CpvAccess(_qd) = new QdState();
844         if (CmiMyRank() == 0) {
845 #if !defined(CMK_CPV_IS_SMP) && !CMK_SHARED_VARS_UNIPROCESSOR
846         CpvAccessOther(_qd, 1) = new QdState(); // for i/o interrupt
847 #endif
848         }
849         _qdHandlerIdx = CmiRegisterHandler((CmiHandler)_qdHandler);
850         _qdCommHandlerIdx = CmiRegisterHandler((CmiHandler)_qdCommHandler);
851         if (CmiGetArgIntDesc(argv,"+qd",&_dummy_dq, "QD time in seconds")) {
852           if (CmiMyPe()==0)
853             CmiPrintf("Charm++> Fake QD using %d seconds.\n", _dummy_dq);
854         }
855 }
856
857 #if CMK_BLUEGENE_CHARM && CMK_CHARMDEBUG
858 void CpdBgInit();
859 #endif
860 void CpdBreakPointInit();
861
862 /**
863   This is the main charm setup routine.  It's called
864   on all processors after Converse initialization.
865   This routine gets passed to Converse from "main.C".
866   
867   The main purpose of this routine is to set up the objects
868   and Ckpv's used during a regular Charm run.  See the comment
869   at the top of the file for overall flow.
870 */
871 void _initCharm(int unused_argc, char **argv)
872
873         int inCommThread = (CmiMyRank() == CmiMyNodeSize());
874
875         DEBUGF(("[%d,%.6lf ] _initCharm started\n",CmiMyPe(),CmiWallTimer()));
876
877         CkpvInitialize(PtrQ*,_buffQ);
878         CkpvInitialize(PtrVec*,_bocInitVec);
879         CkpvInitialize(void*, _currentChare);
880         CkpvInitialize(int,   _currentChareType);
881         CkpvInitialize(CkGroupID, _currentGroup);
882         CkpvInitialize(void *, _currentNodeGroupObj);
883         CkpvInitialize(CkGroupID, _currentGroupRednMgr);
884         CkpvInitialize(GroupTable*, _groupTable);
885         CkpvInitialize(GroupIDTable*, _groupIDTable);
886         CkpvInitialize(CmiImmediateLockType, _groupTableImmLock);
887         CkpvInitialize(UInt, _numGroups);
888         CkpvInitialize(int, _numInitsRecd);
889         CkpvInitialize(char**, Ck_argv); CkpvAccess(Ck_argv)=argv;
890         CkpvInitialize(MsgPool*, _msgPool);
891         CkpvInitialize(CkCoreState *, _coreState);
892         /*
893                 Added for evacuation-sayantan
894         */
895 #ifndef __BLUEGENE__
896         CpvInitialize(char *,_validProcessors);
897         CpvInitialize(char ,startedEvac);
898 #endif
899         CpvInitialize(int,serializer);
900
901         _initChareTables();            // for checkpointable plain chares
902
903         CksvInitialize(UInt, _numNodeGroups);
904         CksvInitialize(GroupTable*, _nodeGroupTable);
905         CksvInitialize(GroupIDTable, _nodeGroupIDTable);
906         CksvInitialize(CmiImmediateLockType, _nodeGroupTableImmLock);
907         CksvInitialize(CmiNodeLock, _nodeLock);
908         CksvInitialize(PtrVec*,_nodeBocInitVec);
909         CksvInitialize(UInt,_numInitNodeMsgs);
910         CkpvInitialize(int,_charmEpoch);
911         CkpvAccess(_charmEpoch)=0;
912         CksvInitialize(int, _triggersSent);
913         CksvAccess(_triggersSent) = 0;
914
915         CkpvInitialize(_CkOutStream*, _ckout);
916         CkpvInitialize(_CkErrStream*, _ckerr);
917         CkpvInitialize(Stats*, _myStats);
918
919         CkpvAccess(_groupIDTable) = new GroupIDTable(0);
920         CkpvAccess(_groupTable) = new GroupTable;
921         CkpvAccess(_groupTable)->init();
922         CkpvAccess(_groupTableImmLock) = CmiCreateImmediateLock();
923         CkpvAccess(_numGroups) = 1; // make 0 an invalid group number
924         CkpvAccess(_buffQ) = new PtrQ();
925         CkpvAccess(_bocInitVec) = new PtrVec();
926
927         CkpvAccess(_currentNodeGroupObj) = NULL;
928
929         if(CkMyRank()==0)
930         {
931                 CksvAccess(_numNodeGroups) = 1; //make 0 an invalid group number
932                 CksvAccess(_numInitNodeMsgs) = 0;
933                 CksvAccess(_nodeLock) = CmiCreateLock();
934                 CksvAccess(_nodeGroupTable) = new GroupTable();
935                 CksvAccess(_nodeGroupTable)->init();
936                 CksvAccess(_nodeGroupTableImmLock) = CmiCreateImmediateLock();
937                 CksvAccess(_nodeBocInitVec) = new PtrVec();
938         }
939
940         CkCallbackInit();
941         
942         CmiNodeAllBarrier();
943
944 #if ! CMK_BLUEGENE_CHARM
945         initQd(argv);         // bigsim calls it in ConverseCommonInit
946 #endif
947
948         CkpvAccess(_coreState)=new CkCoreState();
949
950         CkpvAccess(_numInitsRecd) = 0;
951
952         CkpvAccess(_ckout) = new _CkOutStream();
953         CkpvAccess(_ckerr) = new _CkErrStream();
954
955         _charmHandlerIdx = CkRegisterHandler((CmiHandler)_bufferHandler);
956         _initHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
957         CkNumberHandlerEx(_initHandlerIdx, (CmiHandlerEx)_initHandler, CkpvAccess(_coreState));
958         _roRestartHandlerIdx = CkRegisterHandler((CmiHandler)_roRestartHandler);
959         _exitHandlerIdx = CkRegisterHandler((CmiHandler)_exitHandler);
960         _bocHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
961         CkNumberHandlerEx(_bocHandlerIdx, (CmiHandlerEx)_initHandler, CkpvAccess(_coreState));
962         _infoIdx = CldRegisterInfoFn((CldInfoFn)_infoFn);
963         _triggerHandlerIdx = CkRegisterHandler((CmiHandler)_triggerHandler);
964         _ckModuleInit();
965
966         CldRegisterEstimator((CldEstimator)_charmLoadEstimator);
967
968         _futuresModuleInit(); // part of futures implementation is a converse module
969         _loadbalancerInit();
970         
971 #if CMK_MEM_CHECKPOINT
972         init_memcheckpt(argv);
973 #endif
974
975         initCharmProjections();
976 #if CMK_TRACE_IN_CHARM
977         // initialize trace module in ck
978         traceCharmInit(argv);
979 #endif
980         
981     CkpvInitialize(int, envelopeEventID);
982     CkpvAccess(envelopeEventID) = 0;
983         CkMessageWatcherInit(argv,CkpvAccess(_coreState));
984         
985         /**
986           The rank-0 processor of each node calls the 
987           translator-generated "_register" routines. 
988           
989           _register routines call the charm.h "CkRegister*" routines,
990           which record function pointers and class information for
991           all Charm entities, like Chares, Arrays, and readonlies.
992           
993           There's one _register routine generated for each
994           .ci file.  _register routines *must* be called in the 
995           same order on every node, and *must not* be called by 
996           multiple threads simultaniously.
997         */
998 #ifdef __BLUEGENE__
999         if(BgNodeRank()==0) 
1000 #else
1001         if(CkMyRank()==0)
1002 #endif
1003         {
1004                 CmiArgGroup("Charm++",NULL);
1005                 _parseCommandLineOpts(argv);
1006                 _registerInit();
1007                 CkRegisterMsg("System", 0, 0, CkFreeMsg, sizeof(int));
1008                 CkRegisterChareInCharm(CkRegisterChare("null", 0, TypeChare));
1009                 CkIndex_Chare::__idx=CkRegisterChare("Chare", sizeof(Chare), TypeChare);
1010                 CkRegisterChareInCharm(CkIndex_Chare::__idx);
1011                 CkIndex_Group::__idx=CkRegisterChare("Group", sizeof(Group), TypeGroup);
1012                 CkRegisterChareInCharm(CkIndex_Group::__idx);
1013                 CkRegisterEp("null", (CkCallFnPtr)_nullFn, 0, 0, 0+CK_EP_INTRINSIC);
1014                 
1015                 /**
1016                   These _register calls are for the built-in
1017                   Charm .ci files, like arrays and load balancing.
1018                   If you add a .ci file to charm, you'll have to 
1019                   add a call to the _register routine here, or make
1020                   your library into a "-module".
1021                 */
1022                 _registerCkFutures();
1023                 _registerCkArray();
1024                 _registerLBDatabase();
1025                 _registerCkCallback();
1026                 _registertempo();
1027                 _registerwaitqd();
1028                 _registercharisma();
1029                 _registerCkCheckpoint();
1030 #if CMK_MEM_CHECKPOINT
1031                 _registerCkMemCheckpoint();
1032 #endif
1033                 
1034                 _registerPathHistory();
1035
1036                 /**
1037                   _registerExternalModules is actually generated by 
1038                   charmc at link time (as "moduleinit<pid>.C").  
1039                   
1040                   This generated routine calls the _register functions
1041                   for the .ci files of libraries linked using "-module".
1042                   This funny initialization is most useful for AMPI/FEM
1043                   programs, which don't have a .ci file and hence have
1044                   no other way to control the _register process.
1045                 */
1046                 _registerExternalModules(argv);
1047                 
1048                 /**
1049                   CkRegisterMainModule is generated by the (unique)
1050                   "mainmodule" .ci file.  It will include calls to 
1051                   register all the .ci files.
1052                 */
1053                 CkRegisterMainModule();
1054                 _registerDone();
1055         }
1056         /* The following will happen on every virtual processor in BigEmulator, not just on once per real processor */
1057         if (CkMyRank() == 0) {
1058           CpdBreakPointInit();
1059         }
1060         CmiNodeAllBarrier();
1061
1062     // Execute the initcalls registered in modules
1063         _initCallTable.enumerateInitCalls();
1064
1065 #ifndef CMK_OPTIMIZE
1066         CpdFinishInitialization();
1067 #endif
1068
1069         //CmiNodeAllBarrier();
1070
1071         CkpvAccess(_myStats) = new Stats();
1072         CkpvAccess(_msgPool) = new MsgPool();
1073
1074         CmiNodeAllBarrier();
1075 #if CMK_SMP_TRACE_COMMTHREAD
1076         _TRACE_BEGIN_COMPUTATION();     
1077 #else
1078         if (!inCommThread) {
1079           _TRACE_BEGIN_COMPUTATION();
1080         }
1081 #endif
1082
1083 #ifdef ADAPT_SCHED_MEM
1084     if(CkMyRank()==0){
1085         memCriticalEntries = new int[numMemCriticalEntries];
1086         int memcnt=0;
1087         for(int i=0; i<_entryTable.size(); i++){
1088             if(_entryTable[i]->isMemCritical){
1089                 memCriticalEntries[memcnt++] = i;
1090             }
1091         }
1092     }
1093 #endif
1094
1095 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
1096     _messageLoggingInit();
1097 #endif
1098
1099 #ifndef __BLUEGENE__
1100         /*
1101                 FAULT_EVAC
1102         */
1103         CpvAccess(_validProcessors) = new char[CkNumPes()];
1104         for(int vProc=0;vProc<CkNumPes();vProc++){
1105                 CpvAccess(_validProcessors)[vProc]=1;
1106         }
1107         CpvAccess(startedEvac) = 0;
1108         _ckEvacBcastIdx = CkRegisterHandler((CmiHandler)_ckEvacBcast);
1109         _ckAckEvacIdx = CkRegisterHandler((CmiHandler)_ckAckEvac);
1110 #endif
1111         CpvAccess(serializer) = 0;
1112
1113         evacuate = 0;
1114         CcdCallOnCondition(CcdSIGUSR1,(CcdVoidFn)CkDecideEvacPe,0);
1115 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_)) 
1116     CcdCallOnCondition(CcdSIGUSR2,(CcdVoidFn)CkMlogRestart,0);
1117 #endif
1118
1119         if(_raiseEvac){
1120                 processRaiseEvacFile(_raiseEvacFile);
1121                 /*
1122                 if(CkMyPe() == 2){
1123                 //      CcdCallOnConditionKeep(CcdPERIODIC_10s,(CcdVoidFn)CkDecideEvacPe,0);
1124                         CcdCallFnAfter((CcdVoidFn)CkDecideEvacPe, 0, 10000);
1125                 }
1126                 if(CkMyPe() == 3){
1127                         CcdCallFnAfter((CcdVoidFn)CkDecideEvacPe, 0, 10000);
1128                 }*/
1129         }       
1130
1131     if (!_replaySystem) {
1132         if (faultFunc == NULL) {         // this is not restart
1133             // these two are blocking calls for non-bigsim
1134 #if ! CMK_BLUEGENE_CHARM
1135           CmiInitCPUAffinity(argv);
1136           CmiInitMemAffinity(argv);
1137 #endif
1138         }
1139         CmiInitCPUTopology(argv);
1140     }
1141
1142 #if CMK_BLUEGENE_CHARM && CMK_CHARMDEBUG
1143       // Register the BG handler for CCS. Notice that this is put into a variable shared by
1144       // the whole real processor. This because converse needs to find it. We check that all
1145       // virtual processors register the same index for this handler.
1146     CpdBgInit();
1147 #endif
1148
1149         if (faultFunc) {
1150                 if (CkMyPe()==0) _allStats = new Stats*[CkNumPes()];
1151                 if (!inCommThread) {
1152                   CkArgMsg *msg = (CkArgMsg *)CkAllocMsg(0, sizeof(CkArgMsg), 0);
1153                   msg->argc = CmiGetArgc(argv);
1154                   msg->argv = argv;
1155                   faultFunc(_restartDir, msg);
1156                   CkFreeMsg(msg);
1157                 }
1158         }else if(CkMyPe()==0){
1159                 _allStats = new Stats*[CkNumPes()];
1160                 register size_t i, nMains=_mainTable.size();
1161                 for(i=0;i<nMains;i++)  /* Create all mainchares */
1162                 {
1163                         register int size = _chareTable[_mainTable[i]->chareIdx]->size;
1164                         register void *obj = malloc(size);
1165                         _MEMCHECK(obj);
1166                         _mainTable[i]->setObj(obj);
1167                         CkpvAccess(_currentChare) = obj;
1168                         CkpvAccess(_currentChareType) = _mainTable[i]->chareIdx;
1169                         register CkArgMsg *msg = (CkArgMsg *)CkAllocMsg(0, sizeof(CkArgMsg), 0);
1170                         msg->argc = CmiGetArgc(argv);
1171                         msg->argv = argv;
1172                         _entryTable[_mainTable[i]->entryIdx]->call(msg, obj);
1173 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
1174             CpvAccess(_currentObj) = (Chare *)obj;
1175 #endif
1176                 }
1177                 _mainDone = 1;
1178
1179                 _STATS_RECORD_CREATE_CHARE_N(nMains);
1180                 _STATS_RECORD_PROCESS_CHARE_N(nMains);
1181
1182
1183
1184
1185                 for(i=0;i<_readonlyMsgs.size();i++) /* Send out readonly messages */
1186                 {
1187                         register void *roMsg = (void *) *((char **)(_readonlyMsgs[i]->pMsg));
1188                         if(roMsg==0)
1189                                 continue;
1190                         //Pack the message and send it to all other processors
1191                         register envelope *env = UsrToEnv(roMsg);
1192                         env->setSrcPe(CkMyPe());
1193                         env->setMsgtype(ROMsgMsg);
1194                         env->setRoIdx(i);
1195                         CmiSetHandler(env, _initHandlerIdx);
1196                         CkPackMessage(&env);
1197                         CmiSyncBroadcast(env->getTotalsize(), (char *)env);
1198                         CpvAccess(_qd)->create(CkNumPes()-1);
1199
1200                         //For processor 0, unpack and re-set the global
1201                         CkUnpackMessage(&env);
1202                         _processROMsgMsg(env);
1203                         _numInitMsgs++;
1204                 }
1205
1206                 //Determine the size of the RODataMessage
1207                 PUP::sizer ps;
1208                 for(i=0;i<_readonlyTable.size();i++) _readonlyTable[i]->pupData(ps);
1209
1210                 //Allocate and fill out the RODataMessage
1211                 envelope *env = _allocEnv(RODataMsg, ps.size());
1212                 PUP::toMem pp((char *)EnvToUsr(env));
1213                 for(i=0;i<_readonlyTable.size();i++) _readonlyTable[i]->pupData(pp);
1214
1215                 env->setCount(++_numInitMsgs);
1216                 env->setSrcPe(CkMyPe());
1217                 CmiSetHandler(env, _initHandlerIdx);
1218                 DEBUGF(("[%d,%.6lf] RODataMsg being sent of size %d \n",CmiMyPe(),CmiWallTimer(),env->getTotalsize()));
1219                 CmiSyncBroadcastAndFree(env->getTotalsize(), (char *)env);
1220                 CpvAccess(_qd)->create(CkNumPes()-1);
1221                 _initDone();
1222         }
1223
1224         DEBUGF(("[%d,%d%.6lf] inCommThread %d\n",CmiMyPe(),CmiMyRank(),CmiWallTimer(),inCommThread));
1225         // when I am a communication thread, I don't participate initDone.
1226         if (inCommThread) {
1227                 CkNumberHandlerEx(_bocHandlerIdx,(CmiHandlerEx)_processHandler,
1228                                         CkpvAccess(_coreState));
1229                 CkNumberHandlerEx(_charmHandlerIdx,(CmiHandlerEx)_processHandler
1230 ,
1231                                         CkpvAccess(_coreState));
1232         }
1233
1234 #if CMK_CHARMDEBUG
1235         // Should not use CpdFreeze inside a thread (since this processor is really a user-level thread)
1236        if (CpvAccess(cpdSuspendStartup))
1237        { 
1238           //CmiPrintf("In Parallel Debugging mode .....\n");
1239           CpdFreeze();
1240        }
1241 #endif
1242
1243
1244 #if __FAULT__
1245         if(killFlag){                                                  
1246                 readKillFile();                                        
1247         }
1248 #endif
1249
1250 }
1251
1252 // this is needed because on o2k, f90 programs have to have main in
1253 // fortran90.
1254 extern "C" void fmain_(int *argc,char _argv[][80],int length[])
1255 {
1256   int i;
1257   char **argv = new char*[*argc+2];
1258
1259   for(i=0;i <= *argc;i++) {
1260     if (length[i] < 100) {
1261       _argv[i][length[i]]='\0';
1262       argv[i] = &(_argv[i][0]);
1263     } else {
1264       argv[i][0] = '\0';
1265     }
1266   }
1267   argv[*argc+1]=0;
1268
1269   ConverseInit(*argc, argv, (CmiStartFn) _initCharm, 0, 0);
1270 }
1271
1272 // user callable function to register an exit function, this function
1273 // will perform task of collecting of info from all pes to pe0, and call
1274 // CkExit() on pe0 again to recursively traverse the registered exitFn.
1275 // see trace-summary for an example.
1276 void registerExitFn(CkExitFn fn)
1277 {
1278   _CkExitFnVec.enq(fn);
1279 }
1280
1281 /*@}*/