[project @ 1999-07-06 15:33:23 by simonmar]
[ghc-hetmet.git] / ghc / rts / RtsStartup.c
1 /* -----------------------------------------------------------------------------
2  * $Id: RtsStartup.c,v 1.17 1999/07/06 15:33:23 simonmar Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Main function for a standalone Haskell program.
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #include "Rts.h"
11 #include "RtsAPI.h"
12 #include "RtsUtils.h"
13 #include "RtsFlags.h"  
14 #include "Storage.h"    /* initStorage, exitStorage */
15 #include "StablePriv.h" /* initStablePtrTable */
16 #include "Schedule.h"   /* initScheduler */
17 #include "Stats.h"      /* initStats */
18 #include "Weak.h"
19 #include "Ticky.h"
20
21 #if defined(PROFILING)
22 # include "ProfRts.h"
23 #elif defined(DEBUG)
24 # include "DebugProf.h"
25 #endif
26
27 #ifdef PAR
28 #include "ParInit.h"
29 #include "Parallel.h"
30 #include "LLC.h"
31 #endif
32
33 /*
34  * Flag Structure
35  */
36 struct RTS_FLAGS RtsFlags;
37
38 static int rts_has_started_up = 0;
39
40 void
41 startupHaskell(int argc, char *argv[])
42 {
43 #ifdef ENABLE_WIN32_DLL_SUPPORT
44     int i;
45 #endif
46
47     /* To avoid repeated initialisations of the RTS */
48    if (rts_has_started_up)
49      return;
50    else
51      rts_has_started_up=1;
52
53 #if defined(PAR)
54     int nPEs = 0;                   /* Number of PEs */
55 #endif
56
57     /* The very first thing we do is grab the start time...just in case we're
58      * collecting timing statistics.
59      */
60     start_time();
61
62 #ifdef PAR
63 /*
64  *The parallel system needs to be initialised and synchronised before
65  *the program is run.  
66  */
67     if (*argv[0] == '-') {     /* Look to see whether we're the Main Thread */
68         IAmMainThread = rtsTrue;
69         argv++; argc--;                 /* Strip off flag argument */
70 /*      fprintf(stderr, "I am Main Thread\n"); */
71     }
72     /* 
73      * Grab the number of PEs out of the argument vector, and
74      * eliminate it from further argument processing.
75      */
76     nPEs = atoi(argv[1]);
77     argv[1] = argv[0];
78     argv++; argc--;
79     initEachPEHook();                  /* HWL: hook to be execed on each PE */
80     SynchroniseSystem();
81 #endif
82
83     /* Set the RTS flags to default values. */
84     initRtsFlagsDefaults();
85
86     /* Call the user hook to reset defaults, if present */
87     defaultsHook();
88
89     /* Parse the flags, separating the RTS flags from the programs args */
90     setupRtsFlags(&argc, argv, &rts_argc, rts_argv);
91     prog_argc = argc;
92     prog_argv = argv;
93
94 #ifdef PAR
95    /* Initialise the parallel system -- before initHeap! */
96     initParallelSystem();
97    /* And start GranSim profiling if required: omitted for now
98     *if (Rtsflags.ParFlags.granSimStats)
99     *init_gr_profiling(rts_argc, rts_argv, prog_argc, prog_argv);
100     */
101 #endif  /* PAR */
102
103     /* initialize the storage manager */
104     initStorage();
105
106     /* initialise the stable pointer table */
107     initStablePtrTable();
108
109 #if defined(PROFILING) || defined(DEBUG)
110     initProfiling();
111 #endif
112
113     /* Initialise the scheduler */
114     initScheduler();
115
116     /* Initialise the stats department */
117     initStats();
118
119 #if 0
120     initUserSignals();
121 #endif
122  
123     /* When the RTS and Prelude live in separate DLLs,
124        we need to patch up the char- and int-like tables
125        that the RTS keep after both DLLs have been loaded,
126        filling in the tables with references to where the
127        static info tables have been loaded inside the running
128        process.
129     */
130 #ifdef ENABLE_WIN32_DLL_SUPPORT
131     for(i=0;i<=255;i++)
132        (CHARLIKE_closure[i]).header.info = (const StgInfoTable*)&Czh_static_info;
133
134     for(i=0;i<=32;i++)
135        (INTLIKE_closure[i]).header.info = (const StgInfoTable*)&Izh_static_info;
136        
137 #endif
138     /* Record initialization times */
139     end_init();
140 }
141
142 /*
143  * Shutting down the RTS - two ways of doing this, one which
144  * calls exit(), one that doesn't.
145  *
146  * (shutdownHaskellAndExit() is called by System.exitWith).
147  */
148 void
149 shutdownHaskellAndExit(int n)
150 {
151   OnExitHook();
152   shutdownHaskell();
153   stg_exit(n);
154 }
155
156 void
157 shutdownHaskell(void)
158 {
159   if (!rts_has_started_up)
160      return;
161
162   /* Finalize any remaining weak pointers */
163   finalizeWeakPointersNow();
164
165 #if defined(GRAN)
166   #error FixMe.
167   if (!RTSflags.GranFlags.granSimStats_suppressed)
168     end_gr_simulation();
169 #endif
170
171   /* clean up things from the storage manager's point of view */
172   exitStorage();
173
174 #if defined(PROFILING) || defined(DEBUG)
175   endProfiling();
176 #endif
177
178 #if defined(PROFILING) 
179   report_ccs_profiling( );
180 #endif
181
182 #if defined(TICKY_TICKY)
183   if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
184 #endif
185
186   rts_has_started_up=0;
187 }
188
189
190 /* 
191  * called from STG-land to exit the program
192  */
193
194 void  
195 stg_exit(I_ n)
196 {
197 #ifdef PAR
198   par_exit(n);
199 #else
200   exit(n);
201 #endif
202 }
203