[project @ 1998-11-26 09:17:22 by sof]
[ghc-hetmet.git] / ghc / runtime / main / main.lc
index 8d6d8dc..86f82ce 100644 (file)
@@ -6,8 +6,10 @@
 
 \begin{code}
 #if defined(PROFILING) || defined(PAR) || defined(CONCURRENT)
+#if !defined(_AIX)
 #define NON_POSIX_SOURCE /* time things on Solaris -- sigh */
 #endif
+#endif
 
 #include "rtsdefs.h"
 #include <setjmp.h>
@@ -24,7 +26,7 @@
 /* memory.h and strings.h conflict on some systems.  */
 #endif /* not STDC_HEADERS and not HAVE_STRING_H */
 
-#if defined(PROFILING) || defined(PAR)
+#if defined(PROFILING) || defined(PAR) || defined(GRAN)
 /* need some "time" things */
 
 /* ToDo: This is a mess! Improve ? */
@@ -55,7 +57,7 @@ extern void checkAStack(STG_NO_ARGS);
 
 /* a real nasty Global Variable */
 /* moved to main/TopClosure(13)?.lc -- *one* of them will get linked in
-P_ TopClosure = Main_mainPrimIO_closure;
+P_ TopClosure = GHCmain_mainPrimIO_closure;
  */
 
 /* structure to carry around info about the storage manager */
@@ -66,22 +68,16 @@ extern I_   OkToGC, buckets;
 extern rtsBool TraceSparks, DelaySparks,
                DeferGlobalUpdates;
 
-extern void RunParallelSystem PROTO((P_));
-extern void initParallelSystem(STG_NO_ARGS);
-extern void SynchroniseSystem(STG_NO_ARGS);
+void RunParallelSystem PROTO((P_));
+void initParallelSystem(STG_NO_ARGS);
+void SynchroniseSystem(STG_NO_ARGS);
 
-extern void SetTrace PROTO((W_ address, I_ level/*?*/));
+void SetTrace PROTO((W_ address, I_ level/*?*/));
 #endif
 
-#if defined(GRAN_CHECK) && defined(GRAN)
-extern W_ debug;
-extern W_ event_trace ;
-extern W_ event_trace_all ;
-#endif
-
-extern void *stgAllocForGMP   PROTO((size_t));
-extern void *stgReallocForGMP PROTO ((void *, size_t, size_t));
-extern void  stgDeallocForGMP PROTO ((void *, size_t));
+void *stgAllocForGMP   PROTO((size_t));
+void *stgReallocForGMP PROTO ((void *, size_t, size_t));
+void  stgDeallocForGMP PROTO ((void *, size_t));
 
 /* NeXTs can't just reach out and touch "end", to use in
    distinguishing things in static vs dynamic (malloc'd) memory.
@@ -103,9 +99,19 @@ jmp_buf restart_main;           /* For restarting after a signal */
 int nPEs = 0;              /* Number of PEs */
 #endif
 
-int /* return type of "main" is defined by the C standard */
-main(int argc, char *argv[])
+\end{code}
+
+Setting up and initialising the run-time system:
+(used by main(), and people that don't allow Haskell
+to stay in control.)
+
+\begin{code}
+void
+initRTS(int argc, char *argv[])
 {
+#ifdef GRAN
+ int i;
+#endif
 \end{code}
 
 The very first thing we do is grab the start time...just in case we're
@@ -122,10 +128,9 @@ Manager's requirements.
 
 \begin{code}
 #ifdef PAR
-    if (*argv[0] == '-') {             /* Look to see whether we're the Main Thread */
+    if (*argv[0] == '-') {     /* Look to see whether we're the Main Thread */
        IAmMainThread = rtsTrue;
         argv++; argc--;                        /* Strip off flag argument */
-/*     fprintf(stderr, "I am Main Thread\n"); */
     }
     /* 
      * Grab the number of PEs out of the argument vector, and
@@ -134,10 +139,11 @@ Manager's requirements.
     nPEs = atoi(argv[1]);
     argv[1] = argv[0];
     argv++; argc--;
+    initEachPEHook();                  /* HWL: hook to be execed on each PE */
     SynchroniseSystem();
 #endif
 
-#if defined(PROFILING) || defined(PAR)
+#if defined(PROFILING) || defined(PAR) || defined(GRAN)
     /* setup string indicating time of run -- only used for profiling */
     (void) time_str();
 #endif
@@ -151,7 +157,6 @@ Manager's requirements.
        what statsfile to use (if any); [if so, write the whole
        cmd-line into it]
        
-       This is unlikely to work well in parallel!  KH.
     */
     initRtsFlagsDefaults();
     defaultsHook(); /* the one supplied does nothing;
@@ -175,10 +180,11 @@ Manager's requirements.
     }
 #endif
 
-#if defined(CONCURRENT) && defined(GRAN)
-    if (!no_gr_profile)
+#if defined(GRAN)
+    if (!RTSflags.GranFlags.granSimStats_suppressed)
       if (init_gr_simulation(rts_argc, rts_argv, prog_argc, prog_argv) != 0) {
-         fprintf(stderr, "init_gr_simulation failed!\n"); EXIT(EXIT_FAILURE);
+         fprintf(stderr, "init_gr_simulation failed!\n"); 
+         EXIT(EXIT_FAILURE);
       }
 #endif
 
@@ -228,7 +234,7 @@ Manager's requirements.
     /* Record initialization times */
     end_init();
 
-#if defined(PROFILING) || defined(CONCURRENT)
+#if defined(PROFILING) || defined(CONCURRENT) 
     /* 
      * Both the context-switcher and the cost-center profiler use 
      * a virtual timer.
@@ -263,30 +269,42 @@ Manager's requirements.
     initUserSignals();
 #endif
 
+
+}
+
+int /* return type of "main" is defined by the C standard */
+main(int argc, char *argv[])
+{
+  initRTS(argc,argv);
+
 #ifdef CONCURRENT
+    AvailableStack = AvailableTSO = PrelBase_Z91Z93_closure;
 # if defined(GRAN)                                                 /* HWL */
-    /* RunnableThreadsHd etc. are init in ScheduleThreads */
-    /* 
-     * I'm not sure about this.  Note that this code is for re-initializing
-     * things when a longjmp to restart_main occurs.  --JSM
-     */
-
-# else                                                             /* !GRAN */
-    AvailableStack = AvailableTSO = Nil_closure;
-    RunnableThreadsHd = RunnableThreadsTl = Nil_closure;
-    WaitingThreadsHd = WaitingThreadsTl = Nil_closure;
+    /* Moved in here from ScheduleThreads, to handle a restart_main 
+       (because of a signal) properly. */
+    for (i=0; i<RTSflags.GranFlags.proc; i++) 
+      {
+        RunnableThreadsHd[i] = RunnableThreadsTl[i] = PrelBase_Z91Z93_closure;
+       WaitThreadsHd[i] = WaitThreadsTl[i] = PrelBase_Z91Z93_closure;
+        PendingSparksHd[i][REQUIRED_POOL] = PendingSparksHd[i][ADVISORY_POOL] = 
+        PendingSparksTl[i][REQUIRED_POOL] = PendingSparksTl[i][ADVISORY_POOL] = 
+            NULL; 
+      }
+# else
+    RunnableThreadsHd = RunnableThreadsTl = PrelBase_Z91Z93_closure;
+    WaitingThreadsHd = WaitingThreadsTl = PrelBase_Z91Z93_closure;
     PendingSparksHd[REQUIRED_POOL] = 
       PendingSparksTl[REQUIRED_POOL] = PendingSparksBase[REQUIRED_POOL];
     PendingSparksHd[ADVISORY_POOL] = 
       PendingSparksTl[ADVISORY_POOL] = PendingSparksBase[ADVISORY_POOL];
 # endif
 
-    CurrentTSO = Nil_closure;
+    CurrentTSO = PrelBase_Z91Z93_closure;
 
 # ifdef PAR
     RunParallelSystem(TopClosure);
 # else
-    STKO_LINK(MainStkO) = Nil_closure;
+    STKO_LINK(MainStkO) = PrelBase_Z91Z93_closure;
     ScheduleThreads(TopClosure);
 # endif        /* PAR */
 
@@ -314,7 +332,13 @@ shutdownHaskell(STG_NO_ARGS)
 {
     STOP_TIME_PROFILER;
 
-    if (! exitSM(&StorageMgrInfo)) {
+#if defined(GRAN)
+    /* For some reason this must be before exitSM */
+    if (!RTSflags.GranFlags.granSimStats_suppressed)
+      end_gr_simulation();
+#endif
+
+    if (! exitSM(&StorageMgrInfo) ) {
        fflush(stdout);
        fprintf(stderr, "exitSM failed!\n");
        EXIT(EXIT_FAILURE);
@@ -331,21 +355,10 @@ shutdownHaskell(STG_NO_ARGS)
     if (RTSflags.TickyFlags.showTickyStats) PrintTickyInfo();
 #endif
 
-#if defined(GRAN_CHECK) && defined(GRAN)
-    if (PrintFetchMisses)
-      fprintf(stderr,"Number of fetch misses: %d\n",fetch_misses);
-
-# if defined(COUNT)
-    fprintf(stderr,"COUNT statistics:\n");
-    fprintf(stderr,"  Total number of updates: %u\n",nUPDs);
-    fprintf(stderr,"  Needed to awaken BQ: %u with avg BQ len of: %f\n",
-           nUPDs_BQ,(float)BQ_lens/(float)nUPDs_BQ);
-    fprintf(stderr,"  Number of PAPs: %u\n",nPAPs);
-# endif
-
-    if (!no_gr_profile)
-      end_gr_simulation();
-#endif
+    /* Give the application a chance to do something sensible
+       on-exit
+    */
+    OnExitHook();
 
     fflush(stdout);
     /* This fflush is important, because: if "main" just returns,
@@ -369,7 +382,7 @@ called by @main.lc@ to initialise the string at the start of the run.
 Only used for profiling.
 
 \begin{code}
-#if defined(PROFILING) || defined(CONCURRENT)
+#if defined(PROFILING) || defined(CONCURRENT) || defined(GRAN)
 # include <time.h>
 
 char *
@@ -400,7 +413,7 @@ getErrorHandler(STG_NO_ARGS)
   return (StgInt) errorHandler;
 }
 
-#ifndef PAR
+#if !defined(PAR)
 
 void
 raiseError( handler )