1 /* -----------------------------------------------------------------------------
2 * $Id: RtsStartup.c,v 1.27 2000/01/14 13:17:15 hwloidl 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 #if defined(PROFILING) || defined(DEBUG)
25 # include "ProfHeap.h"
29 #include "GranSimRts.h"
30 #include "ParallelRts.h"
42 struct RTS_FLAGS RtsFlags;
44 static int rts_has_started_up = 0;
46 static ullong startTime = 0;
50 startupHaskell(int argc, char *argv[])
52 #ifdef ENABLE_WIN32_DLL_SUPPORT
56 /* To avoid repeated initialisations of the RTS */
57 if (rts_has_started_up)
62 /* The very first thing we do is grab the start time...just in case we're
63 * collecting timing statistics.
69 * The parallel system needs to be initialised and synchronised before
72 fprintf(stderr, "startupHaskell: argv[0]=%s\n", argv[0]);
73 if (*argv[0] == '-') { /* Look to see whether we're the Main Thread */
74 IAmMainThread = rtsTrue;
75 argv++; argc--; /* Strip off flag argument */
76 // IF_PAR_DEBUG(verbose,
77 fprintf(stderr, "[%x] I am Main Thread\n", mytid);
80 * Grab the number of PEs out of the argument vector, and
81 * eliminate it from further argument processing.
86 initEachPEHook(); /* HWL: hook to be execed on each PE */
89 /* Set the RTS flags to default values. */
90 initRtsFlagsDefaults();
92 /* Call the user hook to reset defaults, if present */
95 /* Parse the flags, separating the RTS flags from the programs args */
96 setupRtsFlags(&argc, argv, &rts_argc, rts_argv);
101 /* NB: this really must be done after processing the RTS flags */
102 fprintf(stderr, "Synchronising system (%d PEs)\n", nPEs);
103 SynchroniseSystem(); // calls initParallelSystem etc
106 /* initialise scheduler data structures (needs to be done before
112 /* And start GranSim profiling if required: */
113 if (RtsFlags.GranFlags.GranSimStats.Full)
114 init_gr_simulation(rts_argc, rts_argv, prog_argc, prog_argv);
116 /* And start GUM profiling if required: */
117 if (RtsFlags.ParFlags.ParStats.Full)
118 init_gr_simulation(rts_argc, rts_argv, prog_argc, prog_argv);
119 #endif /* PAR || GRAN */
121 /* initialize the storage manager */
124 /* initialise the stable pointer table */
125 initStablePtrTable();
127 #if defined(PROFILING) || defined(DEBUG)
131 /* start the ticker */
132 install_vtalrm_handler();
134 initialize_virtual_timer(TICK_MILLISECS);
137 /* start our haskell execution tasks */
142 /* Initialise the stats department */
145 #if !defined(mingw32_TARGET_OS) && !defined(PAR)
146 /* Initialise the user signal handler set */
148 /* Set up handler to run on SIGINT */
149 init_shutdown_handler();
152 /* When the RTS and Prelude live in separate DLLs,
153 we need to patch up the char- and int-like tables
154 that the RTS keep after both DLLs have been loaded,
155 filling in the tables with references to where the
156 static info tables have been loaded inside the running
159 #ifdef ENABLE_WIN32_DLL_SUPPORT
161 (CHARLIKE_closure[i]).header.info = (const StgInfoTable*)&Czh_static_info;
164 (INTLIKE_closure[i]).header.info = (const StgInfoTable*)&Izh_static_info;
167 /* Record initialization times */
172 * Shutting down the RTS - two ways of doing this, one which
173 * calls exit(), one that doesn't.
175 * (shutdownHaskellAndExit() is called by System.exitWith).
178 shutdownHaskellAndExit(int n)
186 shutdownHaskell(void)
188 if (!rts_has_started_up)
191 /* start timing the shutdown */
195 /* Finalize any remaining weak pointers */
196 finalizeWeakPointersNow();
200 /* end_gr_simulation prints global stats if requested -- HWL */
201 if (!RtsFlags.GranFlags.GranSimStats.Suppressed)
205 /* stop all running tasks */
208 /* stop the ticker */
209 initialize_virtual_timer(0);
211 /* reset the standard file descriptors to blocking mode */
212 resetNonBlockingFd(0);
213 resetNonBlockingFd(1);
214 resetNonBlockingFd(2);
216 /* stop timing the shutdown, we're about to print stats */
219 /* clean up things from the storage manager's point of view.
220 * also outputs the stats (+RTS -s) info.
224 #if defined(PROFILING) || defined(DEBUG)
228 #if defined(PROFILING)
229 report_ccs_profiling( );
232 #if defined(TICKY_TICKY)
233 if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
236 rts_has_started_up=0;
239 shutdownParallelSystem(0);
245 * called from STG-land to exit the program