1 /* -----------------------------------------------------------------------------
2 * $Id: RtsStartup.c,v 1.32 2000/03/09 11:49:34 simonmar Exp $
4 * (c) The GHC Team, 1998-1999
6 * Main function for a standalone Haskell program.
8 * ---------------------------------------------------------------------------*/
14 #include "Storage.h" /* initStorage, exitStorage */
15 #include "StablePriv.h" /* initStablePtrTable */
16 #include "Schedule.h" /* initScheduler */
17 #include "Stats.h" /* initStats */
23 #include "StgStartup.h"
25 #if defined(PROFILING) || defined(DEBUG)
27 # include "ProfHeap.h"
31 #include "GranSimRts.h"
32 #include "ParallelRts.h"
44 struct RTS_FLAGS RtsFlags;
46 static int rts_has_started_up = 0;
48 static ullong startTime = 0;
51 static void initModules ( void );
54 startupHaskell(int argc, char *argv[])
56 #ifdef ENABLE_WIN32_DLL_SUPPORT
60 /* To avoid repeated initialisations of the RTS */
61 if (rts_has_started_up)
66 /* The very first thing we do is grab the start time...just in case we're
67 * collecting timing statistics.
73 * The parallel system needs to be initialised and synchronised before
76 fprintf(stderr, "startupHaskell: argv[0]=%s\n", argv[0]);
77 if (*argv[0] == '-') { /* Look to see whether we're the Main Thread */
78 IAmMainThread = rtsTrue;
79 argv++; argc--; /* Strip off flag argument */
80 // IF_PAR_DEBUG(verbose,
81 fprintf(stderr, "[%x] I am Main Thread\n", mytid);
84 * Grab the number of PEs out of the argument vector, and
85 * eliminate it from further argument processing.
90 initEachPEHook(); /* HWL: hook to be execed on each PE */
93 /* Set the RTS flags to default values. */
94 initRtsFlagsDefaults();
96 /* Call the user hook to reset defaults, if present */
99 /* Parse the flags, separating the RTS flags from the programs args */
100 setupRtsFlags(&argc, argv, &rts_argc, rts_argv);
105 /* NB: this really must be done after processing the RTS flags */
106 fprintf(stderr, "Synchronising system (%d PEs)\n", nPEs);
107 SynchroniseSystem(); // calls initParallelSystem etc
110 /* initialise scheduler data structures (needs to be done before
116 /* And start GranSim profiling if required: */
117 if (RtsFlags.GranFlags.GranSimStats.Full)
118 init_gr_simulation(rts_argc, rts_argv, prog_argc, prog_argv);
120 /* And start GUM profiling if required: */
121 if (RtsFlags.ParFlags.ParStats.Full)
122 init_gr_simulation(rts_argc, rts_argv, prog_argc, prog_argv);
123 #endif /* PAR || GRAN */
125 /* initialize the storage manager */
128 /* initialise the stable pointer table */
129 initStablePtrTable();
131 #if defined(PROFILING) || defined(DEBUG)
135 /* run the per-module initialisation code */
136 #if !defined(INTERPRETER)
140 #if defined(PROFILING) || defined(DEBUG)
144 /* start the ticker */
145 install_vtalrm_handler();
146 initialize_virtual_timer(TICK_MILLISECS);
148 /* start our haskell execution tasks */
153 /* Initialise the stats department */
156 #if !defined(mingw32_TARGET_OS) && !defined(PAR)
157 /* Initialise the user signal handler set */
159 /* Set up handler to run on SIGINT, etc. */
160 init_default_handlers();
163 /* When the RTS and Prelude live in separate DLLs,
164 we need to patch up the char- and int-like tables
165 that the RTS keep after both DLLs have been loaded,
166 filling in the tables with references to where the
167 static info tables have been loaded inside the running
170 #ifdef ENABLE_WIN32_DLL_SUPPORT
172 (CHARLIKE_closure[i]).header.info = (const StgInfoTable*)&Czh_static_info;
175 (INTLIKE_closure[i]).header.info = (const StgInfoTable*)&Izh_static_info;
178 /* Record initialization times */
182 /* -----------------------------------------------------------------------------
183 Per-module initialisation
185 This process traverses all the compiled modules in the program
186 starting with "Main", and performing per-module initialisation for
189 So far, two things happen at initialisation time:
191 - we register stable names for each foreign-exported function
192 in that module. This prevents foreign-exported entities, and
193 things they depend on, from being garbage collected.
195 - we supply a unique integer to each statically declared cost
196 centre and cost centre stack in the program.
198 The code generator inserts a small function "__init_<moddule>" in each
199 module and calls the registration functions in each of the modules
200 it imports. So, if we call "__init_Main", each reachable module in the
201 program will be registered.
203 The init* functions are compiled in the same way as STG code,
204 i.e. without normal C call/return conventions. Hence we must use
205 StgRun to call this stuff.
206 -------------------------------------------------------------------------- */
210 /* The init functions use an explicit stack...
212 #define INIT_STACK_SIZE (BLOCK_SIZE * 4)
218 /* this storage will be reclaimed by the garbage collector,
221 init_stack = (F_ *)allocate(INIT_STACK_SIZE / sizeof(W_));
223 StgRun((StgFunPtr)stg_init, NULL/* no reg table */);
226 #endif /* !INTERPRETER */
228 /* -----------------------------------------------------------------------------
229 * Shutting down the RTS - two ways of doing this, one which
230 * calls exit(), one that doesn't.
232 * (shutdownHaskellAndExit() is called by System.exitWith).
233 * -----------------------------------------------------------------------------
236 shutdownHaskellAndExit(int n)
244 shutdownHaskell(void)
246 if (!rts_has_started_up)
249 /* start timing the shutdown */
253 /* Finalize any remaining weak pointers */
254 finalizeWeakPointersNow();
258 /* end_gr_simulation prints global stats if requested -- HWL */
259 if (!RtsFlags.GranFlags.GranSimStats.Suppressed)
263 /* stop all running tasks */
266 /* stop the ticker */
267 initialize_virtual_timer(0);
269 /* reset the standard file descriptors to blocking mode */
270 resetNonBlockingFd(0);
271 resetNonBlockingFd(1);
272 resetNonBlockingFd(2);
274 /* stop timing the shutdown, we're about to print stats */
277 /* clean up things from the storage manager's point of view.
278 * also outputs the stats (+RTS -s) info.
282 #if defined(PROFILING) || defined(DEBUG)
286 #if defined(PROFILING)
287 report_ccs_profiling();
290 #if defined(TICKY_TICKY)
291 if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
294 rts_has_started_up=0;
297 shutdownParallelSystem(0);
303 * called from STG-land to exit the program