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