[project @ 1999-01-26 11:12:41 by simonm]
[ghc-hetmet.git] / ghc / rts / RtsStartup.c
1 /* -----------------------------------------------------------------------------
2  * $Id: RtsStartup.c,v 1.5 1999/01/26 11:12:47 simonm Exp $
3  *
4  * Main function for a standalone Haskell program.
5  *
6  * ---------------------------------------------------------------------------*/
7
8 #include "Rts.h"
9 #include "RtsAPI.h"
10 #include "RtsUtils.h"
11 #include "RtsFlags.h"  
12 #include "Storage.h"    /* initStorage, exitStorage */
13 #include "StablePriv.h" /* initStablePtrTable */
14 #include "Schedule.h"   /* initScheduler */
15 #include "Stats.h"      /* initStats */
16 #include "Weak.h"
17 #include "Ticky.h"
18
19 #if defined(PROFILING)
20 # include "ProfRts.h"
21 #elif defined(DEBUG)
22 # include "DebugProf.h"
23 #endif
24
25 #ifdef PAR
26 #include "ParInit.h"
27 #include "Parallel.h"
28 #include "LLC.h"
29 #endif
30
31 /*
32  * Flag Structure
33  */
34 struct RTS_FLAGS RtsFlags;
35
36 extern void startupHaskell(int argc, char *argv[])
37 {
38 #if defined(PAR)
39     int nPEs = 0;                   /* Number of PEs */
40 #endif
41
42     /* The very first thing we do is grab the start time...just in case we're
43      * collecting timing statistics.
44      */
45     start_time();
46
47 #ifdef PAR
48 /*
49  *The parallel system needs to be initialised and synchronised before
50  *the program is run.  
51  */
52     if (*argv[0] == '-') {     /* Look to see whether we're the Main Thread */
53         IAmMainThread = rtsTrue;
54         argv++; argc--;                 /* Strip off flag argument */
55 /*      fprintf(stderr, "I am Main Thread\n"); */
56     }
57     /* 
58      * Grab the number of PEs out of the argument vector, and
59      * eliminate it from further argument processing.
60      */
61     nPEs = atoi(argv[1]);
62     argv[1] = argv[0];
63     argv++; argc--;
64     initEachPEHook();                  /* HWL: hook to be execed on each PE */
65     SynchroniseSystem();
66 #endif
67
68     /* Set the RTS flags to default values. */
69     initRtsFlagsDefaults();
70
71     /* Call the user hook to reset defaults, if present */
72     defaultsHook();
73
74     /* Parse the flags, separating the RTS flags from the programs args */
75     setupRtsFlags(&argc, argv, &rts_argc, rts_argv);
76     prog_argc = argc;
77     prog_argv = argv;
78
79 #if defined(PAR)
80    /* Initialise the parallel system -- before initHeap! */
81     initParallelSystem();
82    /* And start GranSim profiling if required: omitted for now
83     *if (Rtsflags.ParFlags.granSimStats)
84     *init_gr_profiling(rts_argc, rts_argv, prog_argc, prog_argv);
85     */
86 #endif  /* PAR */
87
88     /* initialize the storage manager */
89     initStorage();
90
91     /* initialise the stable pointer table */
92     initStablePtrTable();
93
94 #if defined(PROFILING) || defined(DEBUG)
95     initProfiling();
96 #endif
97
98     /* Initialise the scheduler */
99     initScheduler();
100
101     /* Initialise the stats department */
102     initStats();
103
104 #if 0
105     initUserSignals();
106 #endif
107
108     /* Record initialization times */
109     end_init();
110 }
111
112 void
113 shutdownHaskell(void)
114 {
115   /* Finalise any remaining weak pointers */
116   finaliseWeakPointersNow();
117
118 #if defined(GRAN)
119   #error FixMe.
120   if (!RTSflags.GranFlags.granSimStats_suppressed)
121     end_gr_simulation();
122 #endif
123
124   /* clean up things from the storage manager's point of view */
125   exitStorage();
126
127 #if defined(PROFILING) || defined(DEBUG)
128   endProfiling();
129 #endif
130
131 #if defined(PROFILING) 
132   report_ccs_profiling( );
133 #endif
134
135 #if defined(TICKY_TICKY)
136   if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
137 #endif
138
139   /*
140     This fflush is important, because: if "main" just returns,
141     then we will end up in pre-supplied exit code that will close
142     streams and flush buffers.  In particular we have seen: it
143     will close fd 0 (stdin), then flush fd 1 (stdout), then <who
144     cares>...
145     
146     But if you're playing with sockets, that "close fd 0" might
147     suggest to the daemon that all is over, only to be presented
148     with more stuff on "fd 1" at the flush.
149     
150     The fflush avoids this sad possibility.
151    */
152   fflush(stdout);
153 }
154
155
156 /* 
157  * called from STG-land to exit the program cleanly 
158  */
159
160 void  
161 stg_exit(I_ n)
162 {
163 #ifdef PAR
164   par_exit(n);
165 #else
166   OnExitHook();
167   exit(n);
168 #endif
169 }