a3d70712b08a62f526c736f9e1303fb9b9a93c78
[charm.git] / src / ck-core / init.c
1 /***************************************************************************
2  * RCS INFORMATION:
3  *
4  *      $RCSfile$
5  *      $Author$        $Locker$                $State$
6  *      $Revision$      $Date$
7  *
8  ***************************************************************************
9  * DESCRIPTION:
10  *
11  ***************************************************************************
12  * REVISION HISTORY:
13  *
14  * $Log$
15  * Revision 2.52  1998-02-27 11:52:04  jyelon
16  * Cleaned up header files, replaced load-balancer.
17  *
18  * Revision 2.51  1998/01/28 17:52:48  milind
19  * Removed unnecessary function calls to tracing functions.
20  * Added macros to turn tracing on and off at runtime.
21  *
22  * Revision 2.50  1997/12/22 21:57:09  jyelon
23  * Changed LDB initialization scheme.
24  *
25  * Revision 2.49  1997/12/12 05:03:41  jyelon
26  * Fixed bug, wasn't doing CmiGrabBuffer.
27  *
28  * Revision 2.48  1997/10/29 23:52:47  milind
29  * Fixed CthInitialize bug on uth machines.
30  *
31  * Revision 2.47  1997/10/03 19:51:35  milind
32  * Made charmc to work again, after inserting trace calls in converse part,
33  * i.e. threads and user events.
34  *
35  * Revision 2.46  1997/08/22 19:29:06  milind
36  * Added user-event tracing.
37  *
38  * Revision 2.45  1997/07/30 17:30:59  jyelon
39  * *** empty log message ***
40  *
41  * Revision 2.44  1997/07/26 16:41:14  jyelon
42  * *** empty log message ***
43  *
44  * Revision 2.43  1997/07/18 21:21:07  milind
45  * all files of the form perf-*.c have been changed to trace-*.c, with
46  * name expansions. For example, perf-proj.c has been changed to
47  * trace-projections.c.
48  * performance.h has been renamed as trace.h, and perfio.c has been
49  * renamed as traceio.c.
50  * Corresponding changes have been made in the Makefile too.
51  * Earlier, there used to be three libck-core-*.a where * was projections,
52  * summary or none. Now, there will be a single libck-core.a and
53  * three libck-trace-*.a where *=projections, summary and none.
54  * The execmode parameter to charmc script has been renamed as
55  * tracemode.
56  * Also, the perfModuleInit function has been renamed as traceModuleInit,
57  * RecdPerfMsg => RecdTraceMsg
58  * CollectPerfFromNodes => CollectTraceFromNodes
59  *
60  * Revision 2.42  1997/07/18 19:14:50  milind
61  * Fixed the perfModuleInit call to pass command-line params.
62  * Also added trace_enqueue call to Charm message handler.
63  *
64  * Revision 2.41  1997/03/24 23:14:03  milind
65  * Made Charm-runtime 64-bit safe by removing conversions of pointers to
66  * integers. Also, removed charm runtime's dependence of unused argv[]
67  * elements being 0. Also, added sim-irix-64 version. It works.
68  *
69  * Revision 2.40  1997/03/14 20:23:50  milind
70  * Made MAXLOGBUFSIZE in projections a commandline parameter.
71  * One can now specify it as "+logsize 10000" on the program
72  * command line.
73  *
74  * Revision 2.39  1996/04/24 22:53:27  jyelon
75  * *** empty log message ***
76  *
77  * Revision 2.38  1996/04/07 19:16:52  jyelon
78  * Was calling StartCharm-callback too soon, moved it later.
79  *
80  * Revision 2.37  1996/03/05 16:09:56  sanjeev
81  * removed CmiSpanTreeInit from StartCharm
82  *
83  * Revision 2.36  1995/11/14 23:22:08  jyelon
84  * handle_bocinitmsg now saves and restores currentChareBlock.
85  *
86  * Revision 2.35  1995/11/13  04:04:33  gursoy
87  * made changes related to initial msg synchronization
88  *
89  * Revision 2.34  1995/11/07  17:53:45  sanjeev
90  * fixed bugs in statistics collection
91  *
92  * Revision 2.33  1995/11/06  22:59:01  sanjeev
93  * fixes for statistics collection
94  *
95  * Revision 2.32  1995/11/06  21:36:29  milind
96  * Removed CldPeriodicCheckInit() call from SysPeriodicCheckInit().
97  *
98  * Revision 2.31  1995/11/06  00:17:42  sanjeev
99  * magic numbers for main-chare and BOCs are not rand()
100  *
101  * Revision 2.30  1995/10/27  21:31:25  jyelon
102  * changed NumPe --> NumPes
103  *
104  * Revision 2.29  1995/10/25  15:48:43  gursoy
105  * added BocInitQueueDestroy function to realese the memory
106  *
107  * Revision 2.28  1995/10/11  17:52:51  sanjeev
108  * fixed Charm++ chare creation
109  *
110  * Revision 2.27  1995/09/30  14:49:36  jyelon
111  * fixed bug: only PE's of rank 0 were registering their handlers.
112  *
113  * Revision 2.26  1995/09/29  09:51:12  jyelon
114  * Many small corrections.
115  *
116  * Revision 2.25  1995/09/26  22:36:55  jyelon
117  * Fixed a bug pertaining to CkInitPhase.
118  *
119  * Revision 2.24  1995/09/26  22:23:17  sanjeev
120  * fixed bug because CkBuffQueue was created too late : moved it up
121  * in StartCharm
122  *
123  * Revision 2.23  1995/09/20  16:36:26  jyelon
124  * *** empty log message ***
125  *
126  * Revision 2.22  1995/09/20  15:41:56  gursoy
127  * added  a new handler index
128  *
129  * Revision 2.21  1995/09/20  14:24:27  jyelon
130  * *** empty log message ***
131  *
132  * Revision 2.20  1995/09/19  17:59:26  sanjeev
133  * removed defaultmainmoduleinit....
134  *
135  * Revision 2.19  1995/09/19  17:57:02  sanjeev
136  * moved Charm's module inits from user_main to InitializeCharm
137  *
138  * Revision 2.18  1995/09/14  20:49:17  jyelon
139  * Added +fifo +lifo +ififo +ilifo +bfifo +blifo command-line options.
140  *
141  * Revision 2.17  1995/09/07  21:21:38  jyelon
142  * Added prefixes to Cpv and Csv macros, fixed bugs thereby revealed.
143  *
144  * Revision 2.16  1995/09/07  05:24:27  gursoy
145  * converted CharmInitLoop to a handler function
146  *
147  * Revision 2.15  1995/09/06  21:48:50  jyelon
148  * Eliminated 'CkProcess_BocMsg', using 'CkProcess_ForChareMsg' instead.
149  *
150  * Revision 2.14  1995/09/06  04:08:58  sanjeev
151  * fixed bugs
152  *
153  * Revision 2.13  1995/09/05  22:00:52  sanjeev
154  * modified StartCharm and ProcessBocInit to integrate Charm++.
155  *
156  * Revision 2.12  1995/09/01  02:13:17  jyelon
157  * VID_BLOCK, CHARE_BLOCK, BOC_BLOCK consolidated.
158  *
159  * Revision 2.11  1995/07/27  20:29:34  jyelon
160  * Improvements to runtime system, general cleanup.
161  *
162  * Revision 2.10  1995/07/24  01:54:40  jyelon
163  * *** empty log message ***
164  *
165  * Revision 2.9  1995/07/22  23:44:13  jyelon
166  * *** empty log message ***
167  *
168  * Revision 2.8  1995/07/19  22:15:26  jyelon
169  * *** empty log message ***
170  *
171  * Revision 2.7  1995/07/12  16:28:45  jyelon
172  * *** empty log message ***
173  *
174  * Revision 2.6  1995/06/29  21:43:17  narain
175  * Added CldCreateBoc
176  *
177  * Revision 2.5  1995/06/29  15:54:09  gursoy
178  * fixed a CpvAccess -- ReadBufIndex
179  *
180  * Revision 2.4  1995/06/20  14:54:24  gursoy
181  * fixed readonly's
182  *
183  * Revision 2.3  1995/06/18  22:10:34  sanjeev
184  * removed CondSendInit
185  *
186  * Revision 2.2  1995/06/13  14:33:55  gursoy
187  * *** empty log message ***
188  *
189  * Revision 1.16  1995/05/03  20:56:44  sanjeev
190  * bug fixes for finding uninitialized modules
191  *
192  * Revision 1.15  1995/05/03  06:28:20  sanjeev
193  * registered _CkNullFunc
194  *
195  * Revision 1.14  1995/05/02  20:37:46  milind
196  * Added _CkNullFunc()
197  *
198  * Revision 1.13  1995/04/25  03:40:01  sanjeev
199  * fixed dynamic boc creation bug in ProcessBocInitMsg
200  *
201  * Revision 1.12  1995/04/23  20:53:14  sanjeev
202  * Removed Core....
203  *
204  * Revision 1.11  1995/04/13  20:54:18  sanjeev
205  * Changed Mc to Cmi
206  *
207  * Revision 1.10  1995/04/06  17:46:21  sanjeev
208  * fixed bug in tracing Charm++ BranchInits
209  *
210  * Revision 1.9  1995/04/02  00:48:57  sanjeev
211  * changes for separating Converse
212  *
213  * Revision 1.8  1995/03/25  18:25:40  sanjeev
214  * *** empty log message ***
215  *
216  * Revision 1.7  1995/03/24  16:42:59  sanjeev
217  * *** empty log message ***
218  *
219  * Revision 1.6  1995/03/21  20:55:23  sanjeev
220  * Changes for new converse names
221  *
222  * Revision 1.5  1995/03/17  23:38:27  sanjeev
223  * changes for better message format
224  *
225  * Revision 1.4  1995/03/12  17:10:39  sanjeev
226  * changes for new msg macros
227  *
228  * Revision 1.3  1994/12/02  00:02:26  sanjeev
229  * interop stuff
230  *
231  * Revision 1.1  1994/11/03  17:39:52  brunner
232  * Initial revision
233  *
234  ***************************************************************************/
235 static char     ident[] = "@(#)$Header$";
236 /***************************************************************************/
237 /* This is the main process that runs on each pe                           */
238 /* */
239 /***************************************************************************/
240 #include "charm.h"
241
242 #include "trace.h"
243
244
245 /* these two variables are set in registerMainChare() */
246 CsvDeclare(int, _CK_MainChareIndex);
247 CsvDeclare(int, _CK_MainEpIndex);
248
249 CsvDeclare(int, ReadBuffSize); /* this is set in registerReadOnly() */
250 CsvStaticDeclare(void **, _CK_9_ReadMsgTable);  /* was previously global */
251
252 CpvDeclare(char*, ReadBufIndex);
253 CpvDeclare(char*, ReadFromBuffer);
254
255 #define BLK_LEN 512
256 CpvStaticDeclare(BOCINIT_QUEUE*, BocInitQueueHead);
257 CpvStaticDeclare(ENVELOPE*, readvarmsg);
258
259 static int EmptyBocInitMsgs();
260 static void *BocInitQueueCreate();
261 static void BocInitQueueDestroy();
262 static void EnQueueBocInitMsgs();
263 static ENVELOPE *DeQueueBocInitMsgs() ;
264
265 /* these store argc, argv for use by CharmInit */
266 CpvStaticDeclare(int,   userArgc);
267 CpvStaticDeclare(char**,  userArgv);
268
269 CpvStaticDeclare(int, NumChildrenDoneWithStartCharm);
270 CpvStaticDeclare(FUNCTION_PTR, UserStartCharmDoneHandler);
271
272 /* all these counts are incremented in register.c */
273 CpvExtern(int,      fnCount);
274 CpvExtern(int,      msgCount);
275 CpvExtern(int,      chareCount);
276 CpvExtern(int,      chareEpsCount);     /* count of chare AND boc eps */
277 CpvExtern(int,      pseudoCount);
278 CpvExtern(int,      readMsgCount);
279 CpvExtern(int,      readCount); /* count of read-only functions. Should be
280                                  * same as total number of modules */
281 CsvStaticDeclare(int, sharedReadCount); /* it holds the value of readCount, */
282                                         /* and it is  shared within node    */
283
284 extern void CPlus_ProcessBocInitMsg();  /* in cplus_node_init.c */
285 extern void CPlus_CallCharmInit();      /* in cplus_node_init.c */
286 extern void CPlus_SetMainChareID();     /* in cplus_node_init.c */
287 extern CHARE_BLOCK *CreateChareBlock();
288
289
290 extern void BUFFER_INCOMING_MSG() ;
291 extern void HANDLE_INCOMING_MSG() ;
292 extern void HANDLE_INIT_MSG();
293
294 void SysPeriodicCheckInit(void);
295 void CharmRegisterHandlers();
296 void InitializeEPTables();
297 void AddSysBocEps(void);
298 void BroadcastCount(void);
299 void SysBocInit(void);
300
301 void initModuleInit()
302 {
303     CpvInitialize(char*, ReadBufIndex);
304     CpvInitialize(char*, ReadFromBuffer);
305     CpvInitialize(BOCINIT_QUEUE*, BocInitQueueHead);
306     CpvInitialize(int, userArgc);
307     CpvInitialize(char**, userArgv);
308     CpvInitialize(ENVELOPE*, readvarmsg);
309     CpvInitialize(int, NumChildrenDoneWithStartCharm);
310     CpvInitialize(FUNCTION_PTR, UserStartCharmDoneHandler);
311
312     CpvAccess(NumChildrenDoneWithStartCharm) = 0;
313     CpvAccess(BocInitQueueHead) = NULL;
314     if (CmiMyRank() == 0) CsvAccess(ReadBuffSize) = 0;
315 }
316
317
318 /*Added By Milind 05/02/95 */
319
320 void _CkNullFunc()
321 {
322         CmiPrintf("[%d] In Null Function: Module Uninitialized\n", CmiMyPe());
323 }
324
325
326 void InitializeCharm(argc, argv)
327 int argc;
328 char **argv;
329 {
330 /* these lines were in user_main */
331   if (CmiMyRank() != 0) CmiNodeBarrier();
332
333   bocModuleInit();
334   ckModuleInit();
335   condsendModuleInit();
336   globalsModuleInit();
337   initModuleInit();
338   mainModuleInit();
339   quiesModuleInit();
340   registerModuleInit();
341   statModuleInit();
342   tblModuleInit(); 
343   futuresModuleInit();
344
345   if (CmiMyRank() == 0) CmiNodeBarrier();
346 }
347
348
349 static void EndInitPhase()
350 {
351   int i;
352   void  *buffMsg;
353   ENVELOPE *bocMsg;
354
355   CpvAccess(CkInitPhase) = 0;
356
357   
358   /* call all the CopyFromBuffer functions for ReadOnly variables.
359    * _CK_9_ReadMsgTable is passed as an arg because it is no longer
360    * global */
361   
362   if (CmiMyPe() != 0) {
363     if (CmiMyRank() == 0) {
364       for (i = 0; i < CsvAccess(sharedReadCount); i++)
365         (CsvAccess(ROCopyFromBufferTable)[i]) (CsvAccess(_CK_9_ReadMsgTable));
366     }
367     CmiFree(CpvAccess(readvarmsg));
368   
369     while ( (bocMsg=DeQueueBocInitMsgs()) != NULL )
370       ProcessBocInitMsg(bocMsg);
371     BocInitQueueDestroy();
372   }
373   
374   /* Charm is finally done Initializing */
375
376   if (CpvAccess(UserStartCharmDoneHandler))
377     CpvAccess(UserStartCharmDoneHandler)();
378   
379   /* process all the non-init messages arrived during the 
380      initialization */
381   while (!FIFO_Empty(CpvAccess(CkBuffQueue))  ) {
382     FIFO_DeQueue(CpvAccess(CkBuffQueue), &buffMsg);
383     CmiSetHandler(buffMsg, CpvAccess(HANDLE_INCOMING_MSG_Index));
384     CmiSyncSendAndFree(CmiMyPe(), GetEnv_TotalSize(buffMsg), buffMsg);
385   }
386 }
387
388
389 static void PropagateInitBarrier()
390 {
391   if (CpvAccess(CkInitPhase) == 0) return;
392
393   if (CpvAccess(CkCountArrived) && CpvAccess(CkInitCount)==0) {
394     /* initialization phase is done, set the flag to 0 */
395     if (CpvAccess(NumChildrenDoneWithStartCharm)==
396         CmiNumSpanTreeChildren(CmiMyPe())) {
397       int parent = CmiSpanTreeParent(CmiMyPe());
398       void *msg = (void *)CkAllocMsg(0);
399       ENVELOPE *henv = ENVELOPE_UPTR(msg);
400       EndInitPhase();
401       if (parent == -1) {
402         SetEnv_msgType(henv, InitBarrierPhase2);
403         CmiSetHandler(henv, CsvAccess(HANDLE_INIT_MSG_Index));
404         CmiSyncBroadcastAndFree(GetEnv_TotalSize(henv), henv); 
405       } else {
406         SetEnv_msgType(henv, InitBarrierPhase1);
407         CmiSetHandler(henv, CsvAccess(HANDLE_INIT_MSG_Index));
408         CmiSyncSendAndFree(parent,GetEnv_TotalSize(henv), henv);
409       }
410     }
411   }
412 }
413
414
415 void StartCharm(argc, argv, donehandler)
416 int argc;
417 char **argv;
418 FUNCTION_PTR donehandler;
419 {
420         int             i;
421         char           *ReadBufMsg;
422
423         CpvAccess(UserStartCharmDoneHandler) = donehandler;
424         CpvAccess(userArgc) = ParseCommandOptions(argc, argv);
425         CpvAccess(userArgv) = argv;
426
427         InitializeMessageMacros();
428
429         /* CmiSpanTreeInit();  already done in CmiInitMc  -- Sanjeev 3/5/96 */
430
431         /* OtherQsInit(); this was combined with CsdInitialize */
432         StatInit();
433         InitializeDynamicBocMsgList();
434         InitializeBocDataTable();
435         InitializeBocIDMessageCountTable();
436         
437         CharmRegisterHandlers();
438
439        /* set the main message handler to buffering handler */
440        /* after initialization phase, it will be assigned to regular handler */
441        CpvAccess(HANDLE_INCOMING_MSG_Index)
442              = CsvAccess(BUFFER_INCOMING_MSG_Index);
443
444         if (CmiMyRank() == 0) InitializeEPTables();
445         CmiNodeBarrier();          
446   
447  
448         /* log_init(); Moved to convcore.c */
449         if(CpvAccess(traceOn))
450           trace_begin_computation();
451         SysBocInit();
452         CpvAccess(msgs_created) = CpvAccess(msgs_processed) = 0;
453
454        /* create the queue for non-init messages arrived
455           during initialization */
456         CpvAccess(CkBuffQueue) = (void *) FIFO_Create();
457
458
459         if (CmiMyPe() == 0)
460         {
461                 CpvAccess(CkCountArrived)=1;
462
463                 CpvAccess(MsgCount) = 0; 
464                                  /* count # of messages being sent to each
465                                  * node. assume an equal number gets sent to
466                                  * every one. if there is a difference, have
467                                  * to modify this somewhat */
468                 CpvAccess(InsideDataInit) = 1;
469
470                 futuresCreateBOC();
471
472                 CpvAccess(InsideDataInit) = 0;
473
474                 if(CpvAccess(traceOn))
475                   trace_begin_charminit();
476                  
477                 CpvAccess(MainDataSize) = CsvAccess(ChareSizesTable)
478                                               [CsvAccess(_CK_MainChareIndex)];
479                 CpvAccess(mainChareBlock) =
480                     CpvAccess(currentChareBlock) = 
481                         CreateChareBlock(CpvAccess(MainDataSize),
482                                          CHAREKIND_CHARE, 
483                                          CpvAccess(nodecharesProcessed)++);
484
485                 if (CsvAccess(MainChareLanguage) == CHARMPLUSPLUS) 
486                         CPlus_SetMainChareID() ;  /* set mainhandle */
487
488
489                 /* Calling CharmInit entry point */
490                 CpvAccess(NumReadMsg) = 0;
491                 CpvAccess(InsideDataInit) = 1;
492
493                 (CsvAccess(EpInfoTable)[CsvAccess(_CK_MainEpIndex)].function)
494                                 (NULL, CpvAccess(currentChareBlock)->chareptr,
495                                    CpvAccess(userArgc), CpvAccess(userArgv));
496                 
497                 CpvAccess(InsideDataInit) = 0;
498                 if(CpvAccess(traceOn))
499                   trace_end_charminit();
500
501                 /* create the buffer for the read only variables */
502                 ReadBufMsg = (char *) CkAllocMsg(CsvAccess(ReadBuffSize));
503                 CpvAccess(ReadBufIndex) = ReadBufMsg;
504                 if (CsvAccess(ReadBuffSize) > 0)
505                         CkMemError(ReadBufMsg);
506
507                 /*
508                  * in Charm++ the CopyToBuffer fns also send out the
509                  * ReadonlyMsgs by calling ReadMsgInit()
510                  */
511                 for (i = 0; i < CsvAccess(sharedReadCount); i++)
512                         (CsvAccess(ROCopyToBufferTable)[i]) ();
513
514                 /*
515                  * we are sending the id of the main chare along with the
516                  * read only message. in future versions, we might eliminate
517                  * this because the functionality can be expressed using
518                  * readonly variables and MyChareID inside the main chare
519                  */
520
521                 BroadcastReadBuffer(ReadBufMsg, CsvAccess(ReadBuffSize), CpvAccess(mainChareBlock));
522
523                 /*
524                  * send a message with the count of initial messages sent so
525                  * far, to all nodes; includes messages for read-buffer and
526                  * bocs
527                  */
528                 BroadcastCount();
529                 
530                 PropagateInitBarrier();
531         }
532         else
533         {
534                 /* This is so that all PEs have consistent magic numbers for 
535                    BOCs. 0 is the magic # of main chare on proc 0, 
536                    all other procs have magic numbers from 1 */
537                 CpvAccess(nodecharesProcessed) = 1 ;
538
539                 /* create the boc init message queue */
540                 CpvAccess(BocInitQueueHead) = (BOCINIT_QUEUE *) BocInitQueueCreate();
541         }
542
543         SysPeriodicCheckInit();
544 }
545
546
547
548 /*
549  * This is the handler for initialization messages 
550  * Start Boc's by allocating and filling the NodeBocTbl. 
551  * When (a) the  "count" message is received and (b) "count" number of initial
552  * messages are received, switch to the regular phase 
553  */
554
555 void HANDLE_INIT_MSG(env)
556 ENVELOPE *env;
557 {
558   int          i;
559   int          id;
560   int          type;
561   void         *usrMsg;
562   
563   CmiGrabBuffer(&env);
564   if ((GetEnv_msgType(env) == BocInitMsg) ||
565       (GetEnv_msgType(env) == ReadMsgMsg))
566     UNPACK(env);
567   usrMsg = USER_MSG_PTR(env);
568   /* Have a valid message now. */
569   type = GetEnv_msgType(env);
570   
571   switch (type)
572     {
573     case BocInitMsg:
574       EnQueueBocInitMsgs(env);
575       CpvAccess(CkInitCount)++;
576       break;
577       
578     case InitCountMsg:
579       CpvAccess(CkCountArrived) = 1;
580       CpvAccess(CkInitCount) -= GetEnv_count(env);
581       CmiFree(env);
582       break;
583       
584     case ReadMsgMsg:
585       id = GetEnv_other_id(env);
586       CsvAccess(_CK_9_ReadMsgTable)[id] = (void *) usrMsg;
587       CpvAccess(CkInitCount)++; 
588       break;
589       
590     case ReadVarMsg:
591       CpvAccess(ReadFromBuffer) = usrMsg;
592       CpvAccess(CkInitCount)++; 
593       
594       /* get the information about the main chare */
595       CpvAccess(mainChareBlock) = (struct chare_block *)
596         GetEnv_chareBlockPtr(env);
597       CpvAccess(mainChare_magic_number) =
598         GetEnv_chare_magic_number(env);
599       if (CsvAccess(MainChareLanguage) == CHARMPLUSPLUS)
600         CPlus_SetMainChareID();
601       CpvAccess(readvarmsg) = env;
602       break;
603       
604     case InitBarrierPhase1:
605       CpvAccess(NumChildrenDoneWithStartCharm)++;
606       CmiFree(env);
607       break;
608       
609     case InitBarrierPhase2:
610       /* set the main handler to the unbuffering one */
611       CpvAccess(HANDLE_INCOMING_MSG_Index) = 
612           CsvAccess(MAIN_HANDLE_INCOMING_MSG_Index);
613       CmiFree(env);
614       break;
615       
616     default:
617       CmiPrintf("** ERROR ** Unknown message type in initialization phase%d\n",type);
618       
619     }
620   PropagateInitBarrier();
621 }
622
623
624
625
626
627 ProcessBocInitMsg(envelope)
628 ENVELOPE       *envelope;
629 {
630   CHARE_BLOCK    *bocBlock;
631   void           *usrMsg = USER_MSG_PTR(envelope);
632   int             current_ep = GetEnv_EP(envelope);
633   EP_STRUCT      *current_epinfo = CsvAccess(EpInfoTable) + current_ep;
634   int             current_bocnum = GetEnv_boc_num(envelope);
635   int             current_msgType = GetEnv_msgType(envelope);
636   int             current_chare = current_epinfo->chareindex;
637   int             current_magic = CpvAccess(nodecharesProcessed)++;
638   CHARE_BLOCK    *prev_chare_block;
639
640   CpvAccess(nodebocInitProcessed)++ ;
641
642   prev_chare_block = CpvAccess(currentChareBlock);
643   CpvAccess(currentChareBlock) = bocBlock = 
644                 CreateChareBlock(CsvAccess(ChareSizesTable)[current_chare], 
645                                         CHAREKIND_BOCNODE, current_magic);
646   bocBlock->x.boc_num = current_bocnum;
647
648   SetBocBlockPtr(current_bocnum, bocBlock);
649   if(CpvAccess(traceOn))
650     trace_begin_execute(envelope);
651   (current_epinfo->function)(usrMsg, bocBlock->chareptr);
652   if(CpvAccess(traceOn))
653     trace_end_execute(current_magic, current_msgType, current_ep);
654   CpvAccess(currentChareBlock) = prev_chare_block;
655
656   /* for dynamic BOC creation, used in node_main.c */
657   return current_bocnum ;
658 }
659
660
661 /* this call can only be made after the clock has been initialized */
662
663 void SysPeriodicCheckInit(void)
664 {
665 }
666
667
668 int 
669 ParseCommandOptions(argc, argv)
670 int             argc;
671 char          **argv;
672 {
673   /* Removed Converse options into ConverseParseCommandOptions. - Sanjeev */
674   /*
675    * configure the chare kernel according to command line parameters.
676    * by convention, chare kernel parameters begin with '+'.
677    */
678   int             i, j, numSysOpts = 0, foundSysOpt = 0, end;
679   int             mainflag = 0, memflag = 0;
680   int             NumPes;
681   if (argc < 1)
682     {
683       CmiPrintf("Too few arguments. Usage> host_prog node_prog [...]\n");
684       exit(1);
685     }
686
687   end = argc;
688   if (CmiMyPe() == 0)
689     mainflag = 1;
690   
691   CpvAccess(QueueingDefault) = CK_QUEUEING_FIFO;
692   for (i = 1; i < end; i++) {
693     foundSysOpt = 0;
694     if (strcmp(argv[i], "+cs") == 0) {
695       CpvAccess(PrintChareStat) = 1;
696       /*
697        * if (mainflag) CmiPrintf("Chare Statistics Turned
698        * On\n");
699        */
700       foundSysOpt = 1;
701     } else if (strcmp(argv[i], "+ss") == 0) {
702       CpvAccess(PrintSummaryStat) = 1;
703       /*
704        * if(mainflag)CmiPrintf("Summary Statistics Turned
705        * On\n");
706        */
707       foundSysOpt = 1;
708     } else if (strcmp(argv[i],"+fifo")==0) {
709       CpvAccess(QueueingDefault) = CK_QUEUEING_FIFO;
710       foundSysOpt = 1;
711     } else if (strcmp(argv[i],"+lifo")==0) {
712       CpvAccess(QueueingDefault) = CK_QUEUEING_LIFO;
713       foundSysOpt = 1;
714     } else if (strcmp(argv[i],"+ififo")==0) {
715       CpvAccess(QueueingDefault) = CK_QUEUEING_IFIFO;
716       foundSysOpt = 1;
717     } else if (strcmp(argv[i],"+ilifo")==0) {
718       CpvAccess(QueueingDefault) = CK_QUEUEING_ILIFO;
719       foundSysOpt = 1;
720     } else if (strcmp(argv[i],"+bfifo")==0) {
721       CpvAccess(QueueingDefault) = CK_QUEUEING_BFIFO;
722       foundSysOpt = 1;
723     } else if (strcmp(argv[i],"+blifo")==0) {
724       CpvAccess(QueueingDefault) = CK_QUEUEING_BLIFO;
725       foundSysOpt = 1;
726     } else if (strcmp(argv[i], "+p") == 0 && i + 1 < argc) {
727       sscanf(argv[i + 1], "%d", &NumPes);
728       foundSysOpt = 2;
729     } else if (sscanf(argv[i], "+p%d", &NumPes) == 1) {
730       foundSysOpt = 1;
731     }
732     if (foundSysOpt) {
733       /* if system option, remove it. */
734       numSysOpts += foundSysOpt;
735       end -= foundSysOpt;
736       for (j = i; j < argc - foundSysOpt; j++) {
737         argv[j] = argv[j + foundSysOpt];
738       }
739       /* reset i because we shuffled everything down one */
740       i--;
741     }
742   }
743   return (argc - numSysOpts);
744 }
745
746
747
748 #define TABLE_SIZE 256
749
750 void CharmRegisterHandlers()
751 {
752   /* Register the Charm handlers with Converse */
753   CsvAccess(BUFFER_INCOMING_MSG_Index)
754     = CmiRegisterHandler(BUFFER_INCOMING_MSG) ;
755   CsvAccess(MAIN_HANDLE_INCOMING_MSG_Index)
756     = CmiRegisterHandler(HANDLE_INCOMING_MSG) ;
757   CsvAccess(HANDLE_INIT_MSG_Index)
758     = CmiRegisterHandler(HANDLE_INIT_MSG);
759 }
760
761 void InitializeEPTables(void)
762 {
763   int             i;
764   int             TotalFns;
765   int             TotalMsgs;
766   int             TotalChares;
767   int             TotalModules;
768   int             TotalReadMsgs;
769   int             TotalPseudos;
770   int             TotalEvents;
771   EP_STRUCT      *epinfo;
772   
773   /*
774    * TotalEps   =  _CK_5mainChareEPCount(); TotalFns    =
775    * _CK_5mainFunctionCount(); TotalMsgs        =  _CK_5mainMessageCount();
776    * TotalChares        =  _CK_5mainChareCount(); TotalBocEps   =
777    * NumSysBocEps + _CK_5mainBranchEPCount();
778    */
779   CsvAccess(TotalEps) = TABLE_SIZE;
780   TotalFns = TABLE_SIZE;
781   TotalMsgs = TABLE_SIZE;
782   TotalChares = TABLE_SIZE;
783   TotalModules = TABLE_SIZE;
784   TotalReadMsgs = TABLE_SIZE;
785   TotalPseudos = TABLE_SIZE;
786   TotalEvents = TABLE_SIZE;
787   
788   /*
789    * this table is used to store all ReadOnly Messages on processors
790    * other than proc 0. After they are received, they are put in the
791    * actual variables in the user program in the ...CopyFromBuffer
792    * functions
793    */
794   CsvAccess(_CK_9_ReadMsgTable) = (void **) 
795     CmiSvAlloc((TotalReadMsgs + 1) * sizeof(void *));
796   if (TotalReadMsgs > 0)
797     CkMemError(CsvAccess(_CK_9_ReadMsgTable));
798   
799   CsvAccess(ROCopyFromBufferTable) = (FUNCTION_PTR *) 
800     CmiSvAlloc((TotalModules + 1) * sizeof(FUNCTION_PTR));
801   
802   CsvAccess(ROCopyToBufferTable) = (FUNCTION_PTR *) 
803     CmiSvAlloc((TotalModules + 1) * sizeof(FUNCTION_PTR));
804   
805   if (TotalModules > 0)
806     {
807       CkMemError(CsvAccess(ROCopyFromBufferTable));
808       CkMemError(CsvAccess(ROCopyToBufferTable));
809     }
810   
811   epinfo=(EP_STRUCT*)CmiSvAlloc((CsvAccess(TotalEps)+1)*sizeof(EP_STRUCT));
812   CsvAccess(EpInfoTable)=epinfo;
813   if (CsvAccess(TotalEps) > 0) {
814     CkMemError(epinfo);
815     memset((char *)epinfo, 0, (CsvAccess(TotalEps)+1)*sizeof(EP_STRUCT));
816     for (i = 0; i < CpvAccess(chareEpsCount); i++)
817       epinfo[i].language = -1;
818   }
819   
820   CsvAccess(_CK_9_GlobalFunctionTable) = (FUNCTION_PTR *) 
821     CmiSvAlloc((TotalFns + 1) * sizeof(FUNCTION_PTR));
822   
823   if (TotalFns > 0)
824     CkMemError(CsvAccess(_CK_9_GlobalFunctionTable));
825   
826   
827   CsvAccess(MsgToStructTable) = (MSG_STRUCT *) 
828     CmiSvAlloc((TotalMsgs + 1) * sizeof(MSG_STRUCT));
829   
830   if (TotalMsgs > 0)
831     CkMemError(CsvAccess(MsgToStructTable));
832   
833   
834   CsvAccess(ChareSizesTable) = (int *) 
835     CmiSvAlloc((TotalChares + 1) * sizeof(int));
836   
837   CsvAccess(ChareNamesTable) = (char **) CmiSvAlloc(TotalChares * sizeof(char *));
838   
839   if (TotalChares > 0)
840     {
841       CkMemError(CsvAccess(ChareSizesTable));
842       CkMemError(CsvAccess(ChareNamesTable));
843     }
844   
845   CsvAccess(EventTable) = (char **) CmiSvAlloc(TotalEvents * sizeof(char *));
846
847   CsvAccess(PseudoTable) = (PSEUDO_STRUCT *) 
848     CmiSvAlloc((TotalPseudos + 1) * sizeof(PSEUDO_STRUCT));
849   
850   if (TotalPseudos > 0)
851     CkMemError(CsvAccess(PseudoTable));
852   
853   
854   
855   /** end of table allocation **/
856   
857   /* Register the NullFunction to detect uninitialized modules */
858   registerMsg("NULLMSG",_CkNullFunc,_CkNullFunc,_CkNullFunc,0) ;
859   registerEp("NULLEP",_CkNullFunc,0,0,0) ;
860   registerChare("NULLCHARE",0,_CkNullFunc) ;
861   registerFunction(_CkNullFunc) ;
862   registerMonotonic("NULLMONO",_CkNullFunc,_CkNullFunc,CHARM) ;
863   registerTable("NULLTABLE",_CkNullFunc,_CkNullFunc) ;
864   registerAccumulator("NULLACC",_CkNullFunc,_CkNullFunc,_CkNullFunc,CHARM) ;
865   
866   /* Register all the built-in BOC's */
867   AddSysBocEps();
868   CsvAccess(NumSysBocEps) = CpvAccess(chareEpsCount);
869
870   /*
871    * This is the top level call to all modules for initialization. It
872    * is generated at link time by charmc, in module_init_fn.c
873    */
874   _CK_module_init_fn();
875   
876   if ( CsvAccess(MainChareLanguage) == -1 ) {
877     CmiPrintf("[%d] ERROR: registerMainChare() not called : uninitialized module exists\n",CmiMyPe()) ;
878   }
879   
880
881
882   
883   /* set all the "Total" variables so that the rest of the modules work */
884   CsvAccess(TotalEps) = CpvAccess(chareEpsCount);
885   TotalFns = CpvAccess(fnCount);
886   TotalMsgs = CpvAccess(msgCount);
887   TotalChares = CpvAccess(chareCount);
888   TotalModules = CpvAccess(readCount);
889   TotalReadMsgs = CpvAccess(readMsgCount);
890   TotalPseudos = CpvAccess(pseudoCount);
891   
892   CsvAccess(sharedReadCount) = CpvAccess(readCount);
893 }
894
895 /* Adding entry points for system branch office chares. */
896 void AddSysBocEps(void)
897 {
898         QDAddSysBocEps();
899         WOVAddSysBocEps();
900         TblAddSysBocEps();
901         AccAddSysBocEps();
902         MonoAddSysBocEps();
903         DynamicAddSysBocEps();
904         StatAddSysBocEps();
905 }
906
907
908 /* Broadcast the count of messages that are received during initialization. */
909 void BroadcastCount(void)
910 {
911         ENVELOPE       *env;
912         void           *dummy_msg;
913         dummy_msg = (int *) CkAllocMsg(sizeof(int));
914         CkMemError(dummy_msg);
915         env = ENVELOPE_UPTR(dummy_msg);
916         SetEnv_msgType(env, InitCountMsg);
917
918         SetEnv_count(env, CpvAccess(currentBocNum) - NumSysBoc + 2 + CpvAccess(NumReadMsg));
919         CmiSetHandler(env,CsvAccess(HANDLE_INIT_MSG_Index));
920         CmiSyncBroadcastAndFree(GetEnv_TotalSize(env),env);
921 }
922
923 static int 
924 EmptyBocInitMsgs()
925 {
926         return (CpvAccess(BocInitQueueHead)->length == 0);
927 }
928
929
930 static void           *
931 BocInitQueueCreate()
932 {
933         BOCINIT_QUEUE  *queue;
934         queue = (BOCINIT_QUEUE *) CmiAlloc(sizeof(BOCINIT_QUEUE));
935         queue->block = (void **) CmiAlloc(sizeof(void *) * BLK_LEN);
936         queue->block_len = BLK_LEN;
937         queue->first = queue->block_len;
938         queue->length = 0;
939         return (void *) queue;
940 }
941
942
943 static void BocInitQueueDestroy()
944 {
945     if (CpvAccess(BocInitQueueHead))
946     { 
947        if (CpvAccess(BocInitQueueHead)->block)
948           CmiFree(CpvAccess(BocInitQueueHead)->block);
949        CmiFree(CpvAccess(BocInitQueueHead));
950     } 
951 }
952
953
954 static void EnQueueBocInitMsgs(envelope)
955 ENVELOPE       *envelope;
956 {
957         int             num = GetEnv_boc_num(envelope);
958         int i ;
959
960         if (num > CpvAccess(BocInitQueueHead)->block_len)
961         {
962                 void          **blk = CpvAccess(BocInitQueueHead)->block;
963                 int             last;
964                 CpvAccess(BocInitQueueHead)->block = (void **) CmiAlloc(sizeof(void *) * (num + BLK_LEN));
965                 last = CpvAccess(BocInitQueueHead)->first + CpvAccess(BocInitQueueHead)->length;
966                 for (i = CpvAccess(BocInitQueueHead)->first; i < last; i++)
967                         CpvAccess(BocInitQueueHead)->block[i] = blk[i];
968                 CpvAccess(BocInitQueueHead)->block[num] = envelope;
969                 CpvAccess(BocInitQueueHead)->length++;
970                 CmiFree(blk);
971         }
972         else
973         {
974                 CpvAccess(BocInitQueueHead)->block[num] = envelope;
975                 CpvAccess(BocInitQueueHead)->length++;
976                 if (CpvAccess(BocInitQueueHead)->first > num)
977                         CpvAccess(BocInitQueueHead)->first = num;
978         }
979 }
980
981
982 static ENVELOPE *DeQueueBocInitMsgs()
983 {
984         ENVELOPE      *envelope;
985         if (CpvAccess(BocInitQueueHead)->length)
986         {
987                 envelope = CpvAccess(BocInitQueueHead)->block[CpvAccess(BocInitQueueHead)->first++];
988                 CpvAccess(BocInitQueueHead)->length--;
989         /*      if (!CpvAccess(BocInitQueueHead)->length)
990                         CpvAccess(BocInitQueueHead)->first = CpvAccess(BocInitQueueHead)->block_len;
991         */
992                 return envelope ;
993         }
994         else
995                 return NULL ;
996 }
997
998 void SysBocInit(void)
999 {
1000         QDBocInit();
1001         TblBocInit();
1002         WOVBocInit();
1003         DynamicBocInit();
1004         StatisticBocInit();
1005 }
1006
1007
1008
1009 void hostep_error(msg, mydata)
1010 void           *msg, *mydata;
1011 {
1012         CmiPrintf("****error*** main chare ep called on node %d.\n",
1013                  CmiMyPe());
1014 }