The event ID of the envelope is now always initialized with a sequential number.
[charm.git] / src / ck-core / init.C
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7 /**
8 \addtogroup CkInit
9 \brief Controls the Charm++ startup process.
10
11 This file runs the entire Charm++ startup process.
12
13 The process begins with every processor finishing the 
14 Converse startup process and calling _initCharm.
15 This routine runs almost the entire Charm++ setup process.
16 It begins by setting up various Cpvs and subsystems.
17
18 The rank 0 processor of each node then does
19 the Charm++ registration, by calling the various _register
20 routines.  
21
22 Now processor 0:
23 <ol>
24 <li>Creates each mainchare, by allocating the chares
25  and calling their constructors with argc/argv.
26  This typically results in a number of chare/group creations.
27 <li>Sends off all readonly data to the other processors.
28 </ol>
29 After _initCharm, processor 0 immediately begins work.
30
31 The other processors, however, must wait until they recieve 
32 the readonly data and all group creations.  They do this by 
33 setting the _charmHandlerIdx to a special "_bufferHandler"
34 which simply saves all normal messages into a special queue.  
35
36 As the startup data (readonlies and group creations) streams
37 into _initHandler, it counts messages until it is fully 
38 initialized, then calls _initDone to clean out the queues 
39 and resume normal operation.  
40
41 Possible race conditions abound during this process,
42 which is probably overly complex.
43 */
44 /*@{*/
45
46 #include "ck.h"
47 #include "trace.h"
48
49 void CkRestartMain(const char* dirname);
50
51 #define  DEBUGF(x)     //CmiPrintf x;
52
53 UChar _defaultQueueing = CK_QUEUEING_FIFO;
54
55 UInt  _printCS = 0;
56 UInt  _printSS = 0;
57
58 UInt  _numExpectInitMsgs = 0;
59 UInt  _numInitMsgs = 0;
60 CksvDeclare(UInt,_numInitNodeMsgs);
61 int   _infoIdx;
62 int   _charmHandlerIdx;
63 int   _initHandlerIdx;
64 int   _roHandlerIdx;
65 int   _roRestartHandlerIdx;
66 int   _bocHandlerIdx;
67 int   _nodeBocHandlerIdx;
68 int   _qdHandlerIdx;
69 int   _qdCommHandlerIdx;
70 int   _triggerHandlerIdx;
71 int   _mainDone = 0;
72 static int   _triggersSent = 0;
73
74 CkOutStream ckout;
75 CkErrStream ckerr;
76 CkInStream  ckin;
77
78 CkpvDeclare(void*,       _currentChare);
79 CkpvDeclare(int,         _currentChareType);
80 CkpvDeclare(CkGroupID,   _currentGroup);
81 CkpvDeclare(void*,       _currentNodeGroupObj);
82 CkpvDeclare(CkGroupID,   _currentGroupRednMgr);
83 CkpvDeclare(GroupTable*, _groupTable);
84 CkpvDeclare(GroupIDTable*, _groupIDTable);
85 CkpvDeclare(CmiImmediateLockType, _groupTableImmLock);
86 CkpvDeclare(UInt, _numGroups);
87
88 CkpvDeclare(CkCoreState *, _coreState);
89
90 CksvDeclare(UInt, _numNodeGroups);
91 CksvDeclare(GroupTable*, _nodeGroupTable);
92 CksvDeclare(GroupIDTable, _nodeGroupIDTable);
93 CksvDeclare(CmiImmediateLockType, _nodeGroupTableImmLock);
94 CksvDeclare(CmiNodeLock, _nodeLock);
95 CksvStaticDeclare(PtrVec*,_nodeBocInitVec);
96 CkpvDeclare(int, _charmEpoch);
97
98 CkpvDeclare(Stats*, _myStats);
99 CkpvDeclare(MsgPool*, _msgPool);
100
101 CkpvDeclare(_CkOutStream*, _ckout);
102 CkpvDeclare(_CkErrStream*, _ckerr);
103
104 CkpvStaticDeclare(int,  _numInitsRecd); /* UInt changed to int */
105 CkpvStaticDeclare(PtrQ*, _buffQ);
106 CkpvStaticDeclare(PtrVec*, _bocInitVec);
107
108 #ifndef CMK_CHARE_USE_PTR
109 CpvExtern(CkVec<void *>, chare_objs);
110 CpvExtern(CkVec<VidBlock *>, vidblocks);
111 #endif
112
113 /*
114         FAULT_EVAC
115 */
116 CpvDeclare(char *, _validProcessors);
117 CpvDeclare(char ,startedEvac);
118
119 int    _exitHandlerIdx;
120
121 static Stats** _allStats = 0;
122
123 static int   _numStatsRecd = 0;
124 static int   _exitStarted = 0;
125
126 static InitCallTable _initCallTable;
127
128 #ifndef CMK_OPTIMIZE
129 #define _STATS_ON(x) (x) = 1
130 #else
131 #define _STATS_ON(x) \
132           CmiPrintf("stats unavailable in optimized version. ignoring...\n");
133 #endif
134
135 // fault tolerance
136 typedef void (*CkFtFn)(const char *, CkArgMsg *);
137 static CkFtFn  faultFunc = NULL;
138 static char* _restartDir;
139
140 #ifdef _FAULT_MLOG_
141 int chkptPeriod=1000;
142 bool parallelRestart=false;
143 extern int BUFFER_TIME; //time spent waiting for buffered messages
144 #endif
145
146 // flag for killing processes 
147 extern int killFlag;
148 // file specifying the processes to be killed
149 extern char *killFile;
150 // function for reading the kill file
151 void readKillFile();
152
153
154 int _defaultObjectQ = 0;            // for obejct queue
155 int _ringexit = 0;                  // for charm exit
156 int _ringtoken = 8;
157
158
159 /*
160         FAULT_EVAC
161
162         flag which marks whether or not to trigger the processor shutdowns
163 */
164 static int _raiseEvac=0;
165 static char *_raiseEvacFile;
166 void processRaiseEvacFile(char *raiseEvacFile);
167
168 static inline void _parseCommandLineOpts(char **argv)
169 {
170   if (CmiGetArgFlagDesc(argv,"+cs", "Print extensive statistics at shutdown"))
171       _STATS_ON(_printCS);
172   if (CmiGetArgFlagDesc(argv,"+ss", "Print summary statistics at shutdown"))
173       _STATS_ON(_printSS);
174   if (CmiGetArgFlagDesc(argv,"+fifo", "Default to FIFO queuing"))
175       _defaultQueueing = CK_QUEUEING_FIFO;
176   if (CmiGetArgFlagDesc(argv,"+lifo", "Default to LIFO queuing"))
177       _defaultQueueing = CK_QUEUEING_LIFO;
178   if (CmiGetArgFlagDesc(argv,"+ififo", "Default to integer-prioritized FIFO queuing"))
179       _defaultQueueing = CK_QUEUEING_IFIFO;
180   if (CmiGetArgFlagDesc(argv,"+ilifo", "Default to integer-prioritized LIFO queuing"))
181       _defaultQueueing = CK_QUEUEING_ILIFO;
182   if (CmiGetArgFlagDesc(argv,"+bfifo", "Default to bitvector-prioritized FIFO queuing"))
183       _defaultQueueing = CK_QUEUEING_BFIFO;
184   if (CmiGetArgFlagDesc(argv,"+blifo", "Default to bitvector-prioritized LIFO queuing"))
185       _defaultQueueing = CK_QUEUEING_BLIFO;
186   if (CmiGetArgFlagDesc(argv,"+objq", "Default to use object queue for every obejct"))
187   {
188 #if CMK_OBJECT_QUEUE_AVAILABLE
189       _defaultObjectQ = 1;
190       if (CkMyPe()==0)
191         CmiPrintf("Charm++> Create object queue for every Charm object.\n");
192 #else
193       CmiAbort("Charm++> Object queue not enabled, recompile Charm++ with CMK_OBJECT_QUEUE_AVAILABLE defined to 1.");
194 #endif
195   }
196   if(CmiGetArgString(argv,"+restart",&_restartDir))
197       faultFunc = CkRestartMain;
198 #if __FAULT__
199   if (CmiGetArgFlagDesc(argv,"+restartaftercrash","restarting this processor after a crash")){  
200 # if CMK_MEM_CHECKPOINT
201       faultFunc = CkMemRestart;
202 # endif
203 #ifdef _FAULT_MLOG_
204             faultFunc = CkMlogRestart;
205 #endif
206       CmiPrintf("[%d] Restarting after crash \n",CmiMyPe());
207   }
208   // reading the killFile
209   if(CmiGetArgStringDesc(argv,"+killFile", &killFile,"Generates SIGKILL on specified processors")){
210     if(faultFunc == NULL){
211       //do not read the killfile if this is a restarting processor
212       killFlag = 1;
213       if(CmiMyPe() == 0){
214         printf("[%d] killFlag set to 1 for file %s\n",CkMyPe(),killFile);
215       }
216     }
217   }
218 #endif
219
220   // shut down program in ring fashion to allow projections output w/o IO error
221   if (CmiGetArgIntDesc(argv,"+ringexit",&_ringtoken, "Program exits in a ring fashion")) 
222   {
223     _ringexit = 1;
224     if (CkMyPe()==0)
225       CkPrintf("Charm++> Program shutdown in token ring (%d).\n", _ringtoken);
226     if (_ringtoken > CkNumPes())  _ringtoken = CkNumPes();
227   }
228         /*
229                 FAULT_EVAC
230
231                 if the argument +raiseevac is present then cause faults
232         */
233         if(CmiGetArgStringDesc(argv,"+raiseevac", &_raiseEvacFile,"Generates processor evacuation on random processors")){
234                 _raiseEvac = 1;
235         }
236 #ifdef _FAULT_MLOG_
237     if(!CmiGetArgIntDesc(argv,"+chkptPeriod",&chkptPeriod,"Set the checkpoint period for the message logging fault tolerance algorithm in seconds")){
238         chkptPeriod = 100;
239     }
240     if(CmiGetArgFlagDesc(argv,"+Parallelrestart", "Parallel Restart with message logging protocol")){
241         parallelRestart = true;
242     }
243     if(!CmiGetArgIntDesc(argv,"+mlog_local_buffer",&_maxBufferedMessages,"# of local messages buffered in the message logging protoocl")){
244         _maxBufferedMessages = 2;
245     }
246     if(!CmiGetArgIntDesc(argv,"+mlog_remote_buffer",&_maxBufferedTicketRequests,"# of remote ticket requests buffered in the message logging protoocl")){
247         _maxBufferedTicketRequests = 2;
248     }
249     if(!CmiGetArgIntDesc(argv,"+mlog_buffer_time",&BUFFER_TIME,"# Time spent waiting for messages to be buffered in the message logging protoocl")){
250         BUFFER_TIME = 2;
251     }
252
253 #endif  
254         /* Anytime migration flag */
255         isAnytimeMigration = CmiTrue;
256         if (CmiGetArgFlagDesc(argv,"+noAnytimeMigration","The program does not require support for anytime migration")) {
257           isAnytimeMigration = CmiFalse;
258         }
259 }
260
261 static void _bufferHandler(void *msg)
262 {
263   DEBUGF(("[%d] _bufferHandler called.\n", CkMyPe()));
264   CkpvAccess(_buffQ)->enq(msg);
265 }
266
267 static void _discardHandler(envelope *env)
268 {
269   DEBUGF(("[%d] _discardHandler called.\n", CkMyPe()));
270   CmiFree(env);
271 }
272
273 #ifndef CMK_OPTIMIZE
274 static inline void _printStats(void)
275 {
276   DEBUGF(("[%d] _printStats\n", CkMyPe()));
277   int i;
278   if(_printSS || _printCS) {
279     Stats *total = new Stats();
280     _MEMCHECK(total);
281     for(i=0;i<CkNumPes();i++)
282       total->combine(_allStats[i]);
283     CkPrintf("Charm Kernel Summary Statistics:\n");
284     for(i=0;i<CkNumPes();i++) {
285       CkPrintf("Proc %d: [%d created, %d processed]\n", i,
286                _allStats[i]->getCharesCreated(),
287                _allStats[i]->getCharesProcessed());
288     }
289     CkPrintf("Total Chares: [%d created, %d processed]\n",
290              total->getCharesCreated(), total->getCharesProcessed());
291   }
292   if(_printCS) {
293     CkPrintf("Charm Kernel Detailed Statistics (R=requested P=processed):\n\n");
294
295     CkPrintf("         Create    Mesgs     Create    Mesgs     Create    Mesgs\n");
296     CkPrintf("         Chare     for       Group     for       Nodegroup for\n");
297     CkPrintf("PE   R/P Mesgs     Chares    Mesgs     Groups    Mesgs     Nodegroups\n");
298     CkPrintf("---- --- --------- --------- --------- --------- --------- ----------\n");
299
300     for(i=0;i<CkNumPes();i++) {
301       CkPrintf("%4d  R  %9d %9d %9d %9d %9d %9d\n      P  %9d %9d %9d %9d %9d %9d\n",i,
302                _allStats[i]->getCharesCreated(),
303                _allStats[i]->getForCharesCreated(),
304                _allStats[i]->getGroupsCreated(),
305                _allStats[i]->getGroupMsgsCreated(),
306                _allStats[i]->getNodeGroupsCreated(),
307                _allStats[i]->getNodeGroupMsgsCreated(),
308                _allStats[i]->getCharesProcessed(),
309                _allStats[i]->getForCharesProcessed(),
310                _allStats[i]->getGroupsProcessed(),
311                _allStats[i]->getGroupMsgsProcessed(),
312                _allStats[i]->getNodeGroupsProcessed(),
313                _allStats[i]->getNodeGroupMsgsProcessed());
314     }
315   }
316 }
317 #else
318 static inline void _printStats(void) {}
319 #endif
320
321 static inline void _sendStats(void)
322 {
323   DEBUGF(("[%d] _sendStats\n", CkMyPe()));
324 #ifndef CMK_OPTIMIZE
325   envelope *env = UsrToEnv(CkpvAccess(_myStats));
326 #else
327   envelope *env = _allocEnv(StatMsg);
328 #endif
329   env->setSrcPe(CkMyPe());
330   CmiSetHandler(env, _exitHandlerIdx);
331   CmiSyncSendAndFree(0, env->getTotalsize(), (char *)env);
332 }
333
334 #ifdef _FAULT_MLOG_
335 extern void _messageLoggingExit();
336 #endif
337
338 static void _exitHandler(envelope *env)
339 {
340   DEBUGF(("exitHandler called on %d msgtype: %d\n", CkMyPe(), env->getMsgtype()));
341   switch(env->getMsgtype()) {
342     case ExitMsg:
343       CkAssert(CkMyPe()==0);
344       if(_exitStarted) {
345         CmiFree(env);
346         return;
347       }
348       _exitStarted = 1;
349       CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
350       CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
351       CkNumberHandler(_nodeBocHandlerIdx, (CmiHandler)_discardHandler);
352       env->setMsgtype(ReqStatMsg);
353       env->setSrcPe(CkMyPe());
354       // if exit in ring, instead of broadcasting, send in ring
355       if (_ringexit){
356         DEBUGF(("[%d] Ring Exit \n",CkMyPe()));
357         const int stride = CkNumPes()/_ringtoken;
358         int pe = 0;
359         while (pe<CkNumPes()) {
360           CmiSyncSend(pe, env->getTotalsize(), (char *)env);
361           pe += stride;
362         }
363         CmiFree(env);
364       }else{
365         CmiSyncBroadcastAllAndFree(env->getTotalsize(), (char *)env);
366       } 
367       break;
368     case ReqStatMsg:
369 #ifdef _FAULT_MLOG_
370         _messageLoggingExit();
371 #endif
372       DEBUGF(("ReqStatMsg on %d\n", CkMyPe()));
373       CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
374       CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
375       CkNumberHandler(_nodeBocHandlerIdx, (CmiHandler)_discardHandler);
376         /*FAULT_EVAC*/
377       if(CmiNodeAlive(CkMyPe())){
378          _sendStats();
379       } 
380       _mainDone = 1; // This is needed because the destructors for
381                      // readonly variables will be called when the program
382                      // exits. If the destructor is called while _mainDone
383                      // is 0, it will assume that the readonly variable was
384                      // declared locally. On all processors other than 0, 
385                      // _mainDone is never set to 1 before the program exits.
386 #ifndef CMK_OPTIMIZE
387       if (_ringexit) traceClose();
388 #endif
389       if (_ringexit) {
390         int stride = CkNumPes()/_ringtoken;
391         int pe = CkMyPe()+1;
392         if (pe < CkNumPes() && pe % stride != 0)
393           CmiSyncSendAndFree(pe, env->getTotalsize(), (char *)env);
394         else
395           CmiFree(env);
396       }
397       else
398         CmiFree(env);
399       if(CkMyPe()){
400         DEBUGF(("[%d] Calling converse exit \n",CkMyPe()));
401         ConverseExit();
402       } 
403       break;
404     case StatMsg:
405       CkAssert(CkMyPe()==0);
406 #ifndef CMK_OPTIMIZE
407       _allStats[env->getSrcPe()] = (Stats*) EnvToUsr(env);
408 #endif
409       _numStatsRecd++;
410       DEBUGF(("StatMsg on %d with %d\n", CkMyPe(), _numStatsRecd));
411                         /*FAULT_EVAC*/
412       if(_numStatsRecd==CkNumValidPes()) {
413         _printStats();
414         DEBUGF(("[%d] Calling converse exit \n",CkMyPe()));
415         ConverseExit();
416       }
417       break;
418     default:
419       CmiAbort("Internal Error(_exitHandler): Unknown-msg-type. Contact Developers.\n");
420   }
421 }
422
423 static inline void _processBufferedBocInits(void)
424 {
425   CkCoreState *ck = CkpvAccess(_coreState);
426   CkNumberHandlerEx(_bocHandlerIdx,(CmiHandlerEx)_processHandler, ck);
427   register int i = 0;
428   PtrVec &inits=*CkpvAccess(_bocInitVec);
429   register int len = inits.size();
430   for(i=0; i<len; i++) {
431     envelope *env = inits[i];
432     if(env==0) continue;
433     if(env->isPacked())
434       CkUnpackMessage(&env);
435     _processBocInitMsg(ck,env);
436   }
437   delete &inits;
438 }
439
440 static inline void _processBufferedNodeBocInits(void)
441 {
442   CkCoreState *ck = CkpvAccess(_coreState);
443   CkNumberHandlerEx(_nodeBocHandlerIdx,(CmiHandlerEx)_processHandler,ck);
444   register int i = 0;
445   PtrVec &inits=*CksvAccess(_nodeBocInitVec);
446   register int len = inits.size();
447   for(i=0; i<len; i++) {
448     envelope *env = inits[i];
449     if(env==0) continue;
450     if(env->isPacked())
451       CkUnpackMessage(&env);
452     _processNodeBocInitMsg(ck,env);
453   }
454   delete &inits;
455 }
456
457 static inline void _processBufferedMsgs(void)
458 {
459   CkNumberHandlerEx(_charmHandlerIdx,(CmiHandlerEx)_processHandler,
460         CkpvAccess(_coreState));
461   envelope *env;
462   while(NULL!=(env=(envelope*)CkpvAccess(_buffQ)->deq())) {
463     if(env->getMsgtype()==NewChareMsg || env->getMsgtype()==NewVChareMsg) {
464       if(env->isForAnyPE())
465         CldEnqueue(CLD_ANYWHERE, env, _infoIdx);
466       else
467         CmiSyncSendAndFree(CkMyPe(), env->getTotalsize(), (char *)env);
468     } else {
469       CmiSyncSendAndFree(CkMyPe(), env->getTotalsize(), (char *)env);
470     }
471   }
472 }
473
474 static int _charmLoadEstimator(void)
475 {
476   return CkpvAccess(_buffQ)->length();
477 }
478
479 static void _sendTriggers(void)
480 {
481   int i, num, first;
482   CmiImmediateLock(CksvAccess(_nodeGroupTableImmLock));
483   if (_triggersSent == 0)
484   {
485     _triggersSent++;
486     num = CmiMyNodeSize();
487     register envelope *env = _allocEnv(RODataMsg);
488     env->setSrcPe(CkMyPe());
489     CmiSetHandler(env, _triggerHandlerIdx);
490     first = CmiNodeFirst(CmiMyNode());
491     for (i=0; i < num; i++)
492       if(first+i != CkMyPe())
493         CmiSyncSend(first+i, env->getTotalsize(), (char *)env);
494     CmiFree(env);
495   }
496   CmiImmediateUnlock(CksvAccess(_nodeGroupTableImmLock));
497 }
498
499 void _initDone(void)
500 {
501   DEBUGF(("[%d] _initDone.\n", CkMyPe()));
502   if (!_triggersSent) _sendTriggers();
503   CkNumberHandler(_triggerHandlerIdx, (CmiHandler)_discardHandler);
504   CmiNodeBarrier();
505   if(CkMyRank() == 0) {
506     _processBufferedNodeBocInits();
507   }
508   CmiNodeBarrier(); // wait for all nodegroups to be created
509   _processBufferedBocInits();
510   DEBUGF(("Reached CmiNodeBarrier(), pe = %d, rank = %d\n", CkMyPe(), CkMyRank()));
511   CmiNodeBarrier();
512   DEBUGF(("Crossed CmiNodeBarrier(), pe = %d, rank = %d\n", CkMyPe(), CkMyRank()));
513   _processBufferedMsgs();
514   CkpvAccess(_charmEpoch)=1;
515 }
516
517 static void _triggerHandler(envelope *env)
518 {
519   if (_numExpectInitMsgs && CkpvAccess(_numInitsRecd) + CksvAccess(_numInitNodeMsgs) == _numExpectInitMsgs)
520   {
521     DEBUGF(("Calling Init Done from _triggerHandler\n"));
522     _initDone();
523   }
524   CmiFree(env);
525 }
526
527 static inline void _processROMsgMsg(envelope *env)
528 {
529   *((char **)(_readonlyMsgs[env->getRoIdx()]->pMsg))=(char *)EnvToUsr(env);
530 }
531
532 static inline void _processRODataMsg(envelope *env)
533 {
534   //Unpack each readonly:
535   PUP::fromMem pu((char *)EnvToUsr(env));
536   for(size_t i=0;i<_readonlyTable.size();i++) _readonlyTable[i]->pupData(pu);
537   CmiFree(env);
538 }
539
540 static void _roRestartHandler(void *msg)
541 {
542   CkAssert(CkMyPe()!=0);
543   register envelope *env = (envelope *) msg;
544   CkpvAccess(_numInitsRecd)+=2;  /*++;*/
545   _numExpectInitMsgs = env->getCount();
546   _processRODataMsg(env);
547 }
548
549 static void _roHandler(void *msg)
550 {
551   CpvAccess(_qd)->process();
552   _roRestartHandler(msg);
553 }
554
555 static void _initHandler(void *msg)
556 {
557   CkAssert(CkMyPe()!=0);
558   register envelope *env = (envelope *) msg;
559   switch (env->getMsgtype()) {
560     case BocInitMsg:
561       if (env->getGroupEpoch()==0)
562         CkpvAccess(_numInitsRecd)++;
563       CpvAccess(_qd)->process();
564       CkpvAccess(_bocInitVec)->insert(env->getGroupNum().idx, env);
565       break;
566     case NodeBocInitMsg:
567       CmiImmediateLock(CksvAccess(_nodeGroupTableImmLock));
568       if (env->getGroupEpoch()==0)
569         CksvAccess(_numInitNodeMsgs)++;
570       CksvAccess(_nodeBocInitVec)->insert(env->getGroupNum().idx, env);
571       CmiImmediateUnlock(CksvAccess(_nodeGroupTableImmLock));
572       CpvAccess(_qd)->process();
573       break;
574     case ROMsgMsg:
575       CkpvAccess(_numInitsRecd)++;
576       CpvAccess(_qd)->process();
577       if(env->isPacked()) CkUnpackMessage(&env);
578       _processROMsgMsg(env);
579       break;
580     case RODataMsg:
581       CkpvAccess(_numInitsRecd)+=2;  /*++;*/
582       CpvAccess(_qd)->process();
583       _numExpectInitMsgs = env->getCount();
584       _processRODataMsg(env);
585       break;
586     default:
587       CmiAbort("Internal Error: Unknown-msg-type. Contact Developers.\n");
588   }
589         DEBUGF(("[%d,%.6lf] _numExpectInitMsgs %d CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs) %d\n",CmiMyPe(),CmiWallTimer(),_numExpectInitMsgs,CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs)));
590   if(_numExpectInitMsgs&&(CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs)>=_numExpectInitMsgs)) {
591     _initDone();
592   }
593 }
594
595 // CkExit: start the termination process, but
596 //   then drop into the scheduler so the user's
597 //   method never returns (which would be confusing).
598 extern "C"
599 void _CkExit(void) 
600 {
601   // Shuts down Converse handlers for the upper layers on this processor
602   //
603   CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
604   CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
605   CkNumberHandler(_nodeBocHandlerIdx, (CmiHandler)_discardHandler);
606   DEBUGF(("[%d] CkExit - _exitStarted:%d %d\n", CkMyPe(), _exitStarted, _exitHandlerIdx));
607
608   if(CkMyPe()==0) {
609     if(_exitStarted)
610       CsdScheduler(-1);
611     envelope *env = _allocEnv(ReqStatMsg);
612     env->setSrcPe(CkMyPe());
613     CmiSetHandler(env, _exitHandlerIdx);
614                 /*FAULT_EVAC*/
615     CmiSyncBroadcastAllAndFree(env->getTotalsize(), (char *)env);
616   } else {
617     envelope *env = _allocEnv(ExitMsg);
618     env->setSrcPe(CkMyPe());
619     CmiSetHandler(env, _exitHandlerIdx);
620     CmiSyncSendAndFree(0, env->getTotalsize(), (char *)env);
621   }
622 #if ! CMK_BLUEGENE_THREAD
623   _TRACE_END_EXECUTE();
624   //Wait for stats, which will call ConverseExit when finished:
625   CsdScheduler(-1);
626 #endif
627 }
628
629 CkQ<CkExitFn> _CkExitFnVec;
630
631 // wrapper of CkExit
632 // traverse _CkExitFnVec to call registered user exit functions
633 // CkExitFn will call CkExit() when finished to make sure other
634 // registered functions get called.
635 extern "C"
636 void CkExit(void)
637 {
638         /*FAULT_EVAC*/
639         DEBUGF(("[%d] CkExit called \n",CkMyPe()));
640   if (!_CkExitFnVec.isEmpty()) {
641     CkExitFn fn = _CkExitFnVec.deq();
642     fn();
643   }
644   else
645     _CkExit();
646 }
647
648 /* This is a routine called in case the application is closing due to a signal.
649    Tear down structures that must be cleaned up even when unclean exit happens.
650    It is called by the machine layer whenever some problem occurs (it is thus up
651    to the machine layer to call this function). */
652 extern "C"
653 void EmergencyExit(void) {
654 #ifndef __BLUEGENE__
655   /* Delete _coreState to force any CkMessageWatcher to close down. */
656   delete CkpvAccess(_coreState);
657 #endif
658 }
659
660 static void _nullFn(void *, void *)
661 {
662   CmiAbort("Null-Method Called. Program may have Unregistered Module!!\n");
663 }
664
665 extern void _registerLBDatabase(void);
666 extern void _registerPathHistory(void);
667 extern void _registerExternalModules(char **argv);
668 extern void _ckModuleInit(void);
669 extern void _loadbalancerInit();
670 #if CMK_MEM_CHECKPOINT
671 extern void init_memcheckpt(char **argv);
672 #endif
673 extern "C" void initCharmProjections();
674 extern "C" void CmiInitCPUTopology(char **argv);
675 extern "C" void CmiInitCPUAffinity(char **argv);
676
677 void _registerInitCall(CkInitCallFn fn, int isNodeCall)
678 {
679   if (isNodeCall) _initCallTable.initNodeCalls.enq(fn);
680   else _initCallTable.initProcCalls.enq(fn);
681 }
682
683 void InitCallTable::enumerateInitCalls()
684 {
685   int i;
686 #ifdef __BLUEGENE__
687   if(BgNodeRank()==0)        // called only once on an emulating node
688 #else
689   if(CkMyRank()==0) 
690 #endif
691   {
692     for (i=0; i<initNodeCalls.length(); i++) initNodeCalls[i]();
693   }
694   // initproc may depend on initnode calls.
695   CmiNodeAllBarrier();
696   for (i=0; i<initProcCalls.length(); i++) initProcCalls[i]();
697 }
698
699 CpvCExtern(int, cpdSuspendStartup);
700 extern "C" void CpdFreeze(void);
701
702 extern int _dummy_dq;
703
704 extern "C" void initQd(char **argv)
705 {
706         CpvInitialize(QdState*, _qd);
707         CpvAccess(_qd) = new QdState();
708         if (CmiMyRank() == 0) {
709 #if !defined(CMK_CPV_IS_SMP) && !CMK_SHARED_VARS_UNIPROCESSOR
710         CpvAccessOther(_qd, 1) = new QdState(); // for i/o interrupt
711 #endif
712         }
713         _qdHandlerIdx = CmiRegisterHandler((CmiHandler)_qdHandler);
714         _qdCommHandlerIdx = CmiRegisterHandler((CmiHandler)_qdCommHandler);
715         if (CmiGetArgIntDesc(argv,"+qd",&_dummy_dq, "QD time in seconds")) {
716           if (CmiMyPe()==0)
717             CmiPrintf("Charm++> Fake QD using %d seconds.\n", _dummy_dq);
718         }
719 }
720
721 /**
722   This is the main charm setup routine.  It's called
723   on all processors after Converse initialization.
724   This routine gets passed to Converse from "main.C".
725   
726   The main purpose of this routine is to set up the objects
727   and Ckpv's used during a regular Charm run.  See the comment
728   at the top of the file for overall flow.
729 */
730 void _initCharm(int unused_argc, char **argv)
731
732         int inCommThread = (CmiMyRank() == CmiMyNodeSize());
733
734         DEBUGF(("[%d,%.6lf ] _initCharm started\n",CmiMyPe(),CmiWallTimer()));
735
736         CkpvInitialize(PtrQ*,_buffQ);
737         CkpvInitialize(PtrVec*,_bocInitVec);
738         CkpvInitialize(void*, _currentChare);
739         CkpvInitialize(int,   _currentChareType);
740         CkpvInitialize(CkGroupID, _currentGroup);
741         CkpvInitialize(void *, _currentNodeGroupObj);
742         CkpvInitialize(CkGroupID, _currentGroupRednMgr);
743         CkpvInitialize(GroupTable*, _groupTable);
744         CkpvInitialize(GroupIDTable*, _groupIDTable);
745         CkpvInitialize(CmiImmediateLockType, _groupTableImmLock);
746         CkpvInitialize(UInt, _numGroups);
747         CkpvInitialize(int, _numInitsRecd);
748         CkpvInitialize(char**, Ck_argv); CkpvAccess(Ck_argv)=argv;
749         CkpvInitialize(MsgPool*, _msgPool);
750         CkpvInitialize(CkCoreState *, _coreState);
751         /*
752                 Added for evacuation-sayantan
753         */
754 #ifndef __BLUEGENE__
755         CpvInitialize(char *,_validProcessors);
756         CpvInitialize(char ,startedEvac);
757 #endif
758         CpvInitialize(int,serializer);
759
760 #ifndef CMK_CHARE_USE_PTR
761           /* chare and vidblock table */
762         CpvInitialize(CkVec<void *>, chare_objs);
763         CpvInitialize(CkVec<VidBlock *>, vidblocks);
764 #endif
765
766         CksvInitialize(UInt, _numNodeGroups);
767         CksvInitialize(GroupTable*, _nodeGroupTable);
768         CksvInitialize(GroupIDTable, _nodeGroupIDTable);
769         CksvInitialize(CmiImmediateLockType, _nodeGroupTableImmLock);
770         CksvInitialize(CmiNodeLock, _nodeLock);
771         CksvInitialize(PtrVec*,_nodeBocInitVec);
772         CksvInitialize(UInt,_numInitNodeMsgs);
773         CkpvInitialize(int,_charmEpoch);
774         CkpvAccess(_charmEpoch)=0;
775
776         CkpvInitialize(_CkOutStream*, _ckout);
777         CkpvInitialize(_CkErrStream*, _ckerr);
778         CkpvInitialize(Stats*, _myStats);
779
780         CkpvAccess(_groupIDTable) = new GroupIDTable(0);
781         CkpvAccess(_groupTable) = new GroupTable;
782         CkpvAccess(_groupTable)->init();
783         CkpvAccess(_groupTableImmLock) = CmiCreateImmediateLock();
784         CkpvAccess(_numGroups) = 1; // make 0 an invalid group number
785         CkpvAccess(_buffQ) = new PtrQ();
786         CkpvAccess(_bocInitVec) = new PtrVec();
787
788         CkpvAccess(_currentNodeGroupObj) = NULL;
789
790         if(CkMyRank()==0)
791         {
792                 CksvAccess(_numNodeGroups) = 1; //make 0 an invalid group number
793                 CksvAccess(_numInitNodeMsgs) = 0;
794                 CksvAccess(_nodeLock) = CmiCreateLock();
795                 CksvAccess(_nodeGroupTable) = new GroupTable();
796                 CksvAccess(_nodeGroupTable)->init();
797                 CksvAccess(_nodeGroupTableImmLock) = CmiCreateImmediateLock();
798                 CksvAccess(_nodeBocInitVec) = new PtrVec();
799         }
800
801         CmiNodeAllBarrier();
802
803 #if ! CMK_BLUEGENE_CHARM
804         initQd(argv);         // bigsim calls it in ConverseCommonInit
805 #endif
806
807         CkpvAccess(_coreState)=new CkCoreState();
808
809         CkpvAccess(_numInitsRecd) = -1;  /*0;*/
810
811         CkpvAccess(_ckout) = new _CkOutStream();
812         CkpvAccess(_ckerr) = new _CkErrStream();
813
814         _charmHandlerIdx = CkRegisterHandler((CmiHandler)_bufferHandler);
815         _initHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
816         _roHandlerIdx = CkRegisterHandler((CmiHandler)_roHandler);
817         _roRestartHandlerIdx = CkRegisterHandler((CmiHandler)_roRestartHandler);
818         _exitHandlerIdx = CkRegisterHandler((CmiHandler)_exitHandler);
819         _bocHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
820         _nodeBocHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
821         _infoIdx = CldRegisterInfoFn((CldInfoFn)_infoFn);
822         _triggerHandlerIdx = CkRegisterHandler((CmiHandler)_triggerHandler);
823         _ckModuleInit();
824
825         CldRegisterEstimator((CldEstimator)_charmLoadEstimator);
826
827         _futuresModuleInit(); // part of futures implementation is a converse module
828         _loadbalancerInit();
829         
830 #if CMK_MEM_CHECKPOINT
831         init_memcheckpt(argv);
832 #endif
833
834         initCharmProjections();
835 #if CMK_TRACE_IN_CHARM
836         // initialize trace module in ck
837         traceCharmInit(argv);
838 #endif
839         
840     CkpvInitialize(int, envelopeEventID);
841     CkpvAccess(envelopeEventID) = 0;
842         CkMessageWatcherInit(argv,CkpvAccess(_coreState));
843         
844         /**
845           The rank-0 processor of each node calls the 
846           translator-generated "_register" routines. 
847           
848           _register routines call the charm.h "CkRegister*" routines,
849           which record function pointers and class information for
850           all Charm entities, like Chares, Arrays, and readonlies.
851           
852           There's one _register routine generated for each
853           .ci file.  _register routines *must* be called in the 
854           same order on every node, and *must not* be called by 
855           multiple threads simultaniously.
856         */
857 #ifdef __BLUEGENE__
858         if(BgNodeRank()==0) 
859 #else
860         if(CkMyRank()==0)
861 #endif
862         {
863                 CmiArgGroup("Charm++",NULL);
864                 _parseCommandLineOpts(argv);
865                 _registerInit();
866                 CkRegisterMsg("System", 0, 0, CkFreeMsg, sizeof(int));
867                 CkRegisterChareInCharm(CkRegisterChare("null", 0, TypeChare));
868                 CkIndex_Chare::__idx=CkRegisterChare("Chare", sizeof(Chare), TypeChare);
869                 CkRegisterChareInCharm(CkIndex_Chare::__idx);
870                 CkIndex_Group::__idx=CkRegisterChare("Group", sizeof(Group), TypeGroup);
871                 CkRegisterChareInCharm(CkIndex_Group::__idx);
872                 CkRegisterEp("null", (CkCallFnPtr)_nullFn, 0, 0, 0+CK_EP_INTRINSIC);
873                 
874                 /**
875                   These _register calls are for the built-in
876                   Charm .ci files, like arrays and load balancing.
877                   If you add a .ci file to charm, you'll have to 
878                   add a call to the _register routine here, or make
879                   your library into a "-module".
880                 */
881                 _registerCkFutures();
882                 _registerCkArray();
883                 _registerLBDatabase();
884                 _registerCkCallback();
885                 _registertempo();
886                 _registerwaitqd();
887                 _registercharisma();
888                 _registerCkCheckpoint();
889 #if CMK_MEM_CHECKPOINT
890                 _registerCkMemCheckpoint();
891 #endif
892                 
893                 _registerPathHistory();
894
895                 /**
896                   _registerExternalModules is actually generated by 
897                   charmc at link time (as "moduleinit<pid>.C").  
898                   
899                   This generated routine calls the _register functions
900                   for the .ci files of libraries linked using "-module".
901                   This funny initialization is most useful for AMPI/FEM
902                   programs, which don't have a .ci file and hence have
903                   no other way to control the _register process.
904                 */
905                 _registerExternalModules(argv);
906                 
907                 /**
908                   CkRegisterMainModule is generated by the (unique)
909                   "mainmodule" .ci file.  It will include calls to 
910                   register all the .ci files.
911                 */
912                 CkRegisterMainModule();
913                 _registerDone();
914         }
915         CmiNodeAllBarrier();
916
917     // Execute the initcalls registered in modules
918         _initCallTable.enumerateInitCalls();
919
920 #ifndef CMK_OPTIMIZE
921 #ifdef __BLUEGENE__
922         if(BgNodeRank()==0)
923 #else
924         if(CkMyRank()==0)
925 #endif
926           CpdFinishInitialization();
927 #endif
928
929         //CmiNodeAllBarrier();
930
931         CkpvAccess(_myStats) = new Stats();
932         CkpvAccess(_msgPool) = new MsgPool();
933
934         CmiNodeAllBarrier();
935 #if CMK_SMP_TRACE_COMMTHREAD
936         _TRACE_BEGIN_COMPUTATION();     
937 #else
938         if (!inCommThread) {
939           _TRACE_BEGIN_COMPUTATION();
940         }
941 #endif
942
943 #ifdef ADAPT_SCHED_MEM
944     if(CkMyRank()==0){
945         memCriticalEntries = new int[numMemCriticalEntries];
946         int memcnt=0;
947         for(int i=0; i<_entryTable.size(); i++){
948             if(_entryTable[i]->isMemCritical){
949                 memCriticalEntries[memcnt++] = i;
950             }
951         }
952     }
953 #endif
954
955 #ifdef _FAULT_MLOG_
956     _messageLoggingInit();
957 #endif
958
959 #ifndef __BLUEGENE__
960         /*
961                 FAULT_EVAC
962         */
963         CpvAccess(_validProcessors) = new char[CkNumPes()];
964         for(int vProc=0;vProc<CkNumPes();vProc++){
965                 CpvAccess(_validProcessors)[vProc]=1;
966         }
967         CpvAccess(startedEvac) = 0;
968         _ckEvacBcastIdx = CkRegisterHandler((CmiHandler)_ckEvacBcast);
969         _ckAckEvacIdx = CkRegisterHandler((CmiHandler)_ckAckEvac);
970 #endif
971         CpvAccess(serializer) = 0;
972
973         evacuate = 0;
974         CcdCallOnCondition(CcdSIGUSR1,(CcdVoidFn)CkDecideEvacPe,0);
975 #ifdef _FAULT_MLOG_ 
976     CcdCallOnCondition(CcdSIGUSR2,(CcdVoidFn)CkMlogRestart,0);
977 #endif
978
979         if(_raiseEvac){
980                 processRaiseEvacFile(_raiseEvacFile);
981                 /*
982                 if(CkMyPe() == 2){
983                 //      CcdCallOnConditionKeep(CcdPERIODIC_10s,(CcdVoidFn)CkDecideEvacPe,0);
984                         CcdCallFnAfter((CcdVoidFn)CkDecideEvacPe, 0, 10000);
985                 }
986                 if(CkMyPe() == 3){
987                         CcdCallFnAfter((CcdVoidFn)CkDecideEvacPe, 0, 10000);
988                 }*/
989         }       
990         
991 #if ! CMK_BLUEGENE_CHARM
992         if (faultFunc == NULL) {         // this is not restart
993             // blocking calls
994           CmiInitCPUAffinity(argv);
995           CmiInitCPUTopology(argv);
996         }
997 #endif
998
999         if (faultFunc) {
1000                 if (CkMyPe()==0) _allStats = new Stats*[CkNumPes()];
1001                 if (!inCommThread) {
1002                   CkArgMsg *msg = (CkArgMsg *)CkAllocMsg(0, sizeof(CkArgMsg), 0);
1003                   msg->argc = CmiGetArgc(argv);
1004                   msg->argv = argv;
1005                   faultFunc(_restartDir, msg);
1006                   CkFreeMsg(msg);
1007                 }
1008         }else if(CkMyPe()==0){
1009                 _allStats = new Stats*[CkNumPes()];
1010                 register size_t i, nMains=_mainTable.size();
1011                 for(i=0;i<nMains;i++)  /* Create all mainchares */
1012                 {
1013                         register int size = _chareTable[_mainTable[i]->chareIdx]->size;
1014                         register void *obj = malloc(size);
1015                         _MEMCHECK(obj);
1016                         _mainTable[i]->setObj(obj);
1017                         CkpvAccess(_currentChare) = obj;
1018                         CkpvAccess(_currentChareType) = _mainTable[i]->chareIdx;
1019                         register CkArgMsg *msg = (CkArgMsg *)CkAllocMsg(0, sizeof(CkArgMsg), 0);
1020                         msg->argc = CmiGetArgc(argv);
1021                         msg->argv = argv;
1022                         _entryTable[_mainTable[i]->entryIdx]->call(msg, obj);
1023 #ifdef _FAULT_MLOG_
1024             CpvAccess(_currentObj) = (Chare *)obj;
1025 #endif
1026                 }
1027                 _mainDone = 1;
1028
1029                 _STATS_RECORD_CREATE_CHARE_N(nMains);
1030                 _STATS_RECORD_PROCESS_CHARE_N(nMains);
1031
1032
1033
1034
1035                 for(i=0;i<_readonlyMsgs.size();i++) /* Send out readonly messages */
1036                 {
1037                         register void *roMsg = (void *) *((char **)(_readonlyMsgs[i]->pMsg));
1038                         if(roMsg==0)
1039                                 continue;
1040                         //Pack the message and send it to all other processors
1041                         register envelope *env = UsrToEnv(roMsg);
1042                         env->setSrcPe(CkMyPe());
1043                         env->setMsgtype(ROMsgMsg);
1044                         env->setRoIdx(i);
1045                         CmiSetHandler(env, _initHandlerIdx);
1046                         CkPackMessage(&env);
1047                         CmiSyncBroadcast(env->getTotalsize(), (char *)env);
1048                         CpvAccess(_qd)->create(CkNumPes()-1);
1049
1050                         //For processor 0, unpack and re-set the global
1051                         CkUnpackMessage(&env);
1052                         _processROMsgMsg(env);
1053                         _numInitMsgs++;
1054                 }
1055
1056                 //Determine the size of the RODataMessage
1057                 PUP::sizer ps;
1058                 for(i=0;i<_readonlyTable.size();i++) _readonlyTable[i]->pupData(ps);
1059
1060                 //Allocate and fill out the RODataMessage
1061                 envelope *env = _allocEnv(RODataMsg, ps.size());
1062                 PUP::toMem pp((char *)EnvToUsr(env));
1063                 for(i=0;i<_readonlyTable.size();i++) _readonlyTable[i]->pupData(pp);
1064
1065                 env->setCount(++_numInitMsgs);
1066                 env->setSrcPe(CkMyPe());
1067                 CmiSetHandler(env, _initHandlerIdx);
1068                 DEBUGF(("[%d,%.6lf] RODataMsg being sent of size %d \n",CmiMyPe(),CmiWallTimer(),env->getTotalsize()));
1069                 CmiSyncBroadcastAndFree(env->getTotalsize(), (char *)env);
1070                 CpvAccess(_qd)->create(CkNumPes()-1);
1071                 _initDone();
1072         }
1073
1074         DEBUGF(("[%d,%d%.6lf] inCommThread %d\n",CmiMyPe(),CmiMyRank(),CmiWallTimer(),inCommThread));
1075         // when I am a communication thread, I don't participate initDone.
1076         if (inCommThread) {
1077                 CkNumberHandlerEx(_bocHandlerIdx,(CmiHandlerEx)_processHandler,
1078                                         CkpvAccess(_coreState));
1079                 CkNumberHandlerEx(_charmHandlerIdx,(CmiHandlerEx)_processHandler
1080 ,
1081                                         CkpvAccess(_coreState));
1082         }
1083
1084 #if CMK_CCS_AVAILABLE
1085        if (CpvAccess(cpdSuspendStartup))
1086        { 
1087           //CmiPrintf("In Parallel Debugging mode .....\n");
1088           CpdFreeze();
1089        }
1090 #endif
1091
1092
1093 #if __FAULT__
1094         if(killFlag){                                                  
1095                 readKillFile();                                        
1096         }
1097 #endif
1098
1099 }
1100
1101 // this is needed because on o2k, f90 programs have to have main in
1102 // fortran90.
1103 extern "C" void fmain_(int *argc,char _argv[][80],int length[])
1104 {
1105   int i;
1106   char **argv = new char*[*argc+2];
1107
1108   for(i=0;i <= *argc;i++) {
1109     if (length[i] < 100) {
1110       _argv[i][length[i]]='\0';
1111       argv[i] = &(_argv[i][0]);
1112     } else {
1113       argv[i][0] = '\0';
1114     }
1115   }
1116   argv[*argc+1]=0;
1117
1118   ConverseInit(*argc, argv, (CmiStartFn) _initCharm, 0, 0);
1119 }
1120
1121 // user callable function to register an exit function, this function
1122 // will perform task of collecting of info from all pes to pe0, and call
1123 // CkExit() on pe0 again to recursively traverse the registered exitFn.
1124 // see trace-summary for an example.
1125 void registerExitFn(CkExitFn fn)
1126 {
1127   _CkExitFnVec.enq(fn);
1128 }
1129
1130 /*@}*/