[project @ 1999-07-02 09:31:54 by simonmar]
[ghc-hetmet.git] / ghc / rts / RtsStartup.c
1 /* -----------------------------------------------------------------------------
2  * $Id: RtsStartup.c,v 1.15 1999/07/02 09:31:54 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 void
143 shutdownHaskell(void)
144 {
145   if (!rts_has_started_up)
146      return;
147
148   /* Finalize any remaining weak pointers */
149   finalizeWeakPointersNow();
150
151 #if defined(GRAN)
152   #error FixMe.
153   if (!RTSflags.GranFlags.granSimStats_suppressed)
154     end_gr_simulation();
155 #endif
156
157   /* clean up things from the storage manager's point of view */
158   exitStorage();
159
160 #if defined(PROFILING) || defined(DEBUG)
161   endProfiling();
162 #endif
163
164 #if defined(PROFILING) 
165   report_ccs_profiling( );
166 #endif
167
168 #if defined(TICKY_TICKY)
169   if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
170 #endif
171
172   rts_has_started_up=0;
173 }
174
175
176 /* 
177  * called from STG-land to exit the program cleanly 
178  */
179
180 void  
181 stg_exit(I_ n)
182 {
183 #ifdef PAR
184   par_exit(n);
185 #else
186   OnExitHook();
187   exit(n);
188 #endif
189 }