[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / rts / RtsStartup.c
1 /* -----------------------------------------------------------------------------
2  * $Id: RtsStartup.c,v 1.2 1998/12/02 13:28:41 simonm Exp $
3  *
4  * Main function for a standalone Haskell program.
5  *
6  * ---------------------------------------------------------------------------*/
7
8 #include "Rts.h"
9 #include "RtsAPI.h"
10 #include "RtsUtils.h"
11 #include "RtsFlags.h"  
12 #include "Storage.h"    /* initStorage, exitStorage */
13 #include "StablePtr.h"  /* initStablePtrTable */
14 #include "Schedule.h"   /* initScheduler */
15 #include "Stats.h"      /* initStats */
16 #include "Weak.h"
17
18 #if defined(PROFILING)
19 # include "ProfRTS.h"
20 #elif defined(DEBUG)
21 # include "DebugProf.h"
22 #endif
23
24 #ifdef PAR
25 #include "ParInit.h"
26 #include "Parallel.h"
27 #include "LLC.h"
28 #endif
29
30 /*
31  * Flag Structure
32  */
33 struct RTS_FLAGS RtsFlags;
34
35 extern void startupHaskell(int argc, char *argv[])
36 {
37 #if defined(PAR)
38     int nPEs = 0;                   /* Number of PEs */
39 #endif
40
41     /* The very first thing we do is grab the start time...just in case we're
42      * collecting timing statistics.
43      */
44     start_time();
45
46 #ifdef PAR
47 /*
48  *The parallel system needs to be initialised and synchronised before
49  *the program is run.  
50  */
51     if (*argv[0] == '-') {     /* Look to see whether we're the Main Thread */
52         IAmMainThread = rtsTrue;
53         argv++; argc--;                 /* Strip off flag argument */
54 /*      fprintf(stderr, "I am Main Thread\n"); */
55     }
56     /* 
57      * Grab the number of PEs out of the argument vector, and
58      * eliminate it from further argument processing.
59      */
60     nPEs = atoi(argv[1]);
61     argv[1] = argv[0];
62     argv++; argc--;
63     initEachPEHook();                  /* HWL: hook to be execed on each PE */
64     SynchroniseSystem();
65 #endif
66
67     /* Set the RTS flags to default values. */
68     initRtsFlagsDefaults();
69
70     /* Call the user hook to reset defaults, if present */
71     defaultsHook();
72
73     /* Parse the flags, separating the RTS flags from the programs args */
74     setupRtsFlags(&argc, argv, &rts_argc, rts_argv);
75     prog_argc = argc;
76     prog_argv = argv;
77
78 #if defined(PAR)
79    /* Initialise the parallel system -- before initHeap! */
80     initParallelSystem();
81    /* And start GranSim profiling if required: omitted for now
82     *if (Rtsflags.ParFlags.granSimStats)
83     *init_gr_profiling(rts_argc, rts_argv, prog_argc, prog_argv);
84     */
85 #endif  /* PAR */
86
87     /* initialize the storage manager */
88     initStorage();
89
90     /* initialise the stable pointer table */
91     initStablePtrTable();
92
93 #if defined(PROFILING) || defined(DEBUG)
94     initProfiling();
95 #endif
96
97     /* Initialise the scheduler */
98     initScheduler();
99
100     /* Initialise the stats department */
101     initStats();
102
103 #if 0
104     initUserSignals();
105 #endif
106
107     /* Record initialization times */
108     end_init();
109 }
110
111 void
112 shutdownHaskell(void)
113 {
114   /* Finalise any remaining weak pointers */
115   finaliseWeakPointersNow();
116
117 #if defined(GRAN)
118   #error FixMe.
119   if (!RTSflags.GranFlags.granSimStats_suppressed)
120     end_gr_simulation();
121 #endif
122
123   /* clean up things from the storage manager's point of view */
124   exitStorage();
125
126 #if defined(PROFILING) || defined(DEBUG)
127   endProfiling();
128 #endif
129
130 #if defined(PROFILING) 
131   report_ccs_profiling( );
132 #endif
133
134 #if defined(TICKY_TICKY)
135   #error FixMe.
136   if (RTSflags.TickyFlags.showTickyStats) PrintTickyInfo();
137 #endif
138
139   /*
140     This fflush is important, because: if "main" just returns,
141     then we will end up in pre-supplied exit code that will close
142     streams and flush buffers.  In particular we have seen: it
143     will close fd 0 (stdin), then flush fd 1 (stdout), then <who
144     cares>...
145     
146     But if you're playing with sockets, that "close fd 0" might
147     suggest to the daemon that all is over, only to be presented
148     with more stuff on "fd 1" at the flush.
149     
150     The fflush avoids this sad possibility.
151    */
152   fflush(stdout);
153 }
154
155
156 /* 
157  * called from STG-land to exit the program cleanly 
158  */
159
160 void  
161 stg_exit(I_ n)
162 {
163 #ifdef PAR
164   par_exit(n);
165 #else
166   OnExitHook();
167   exit(n);
168 #endif
169 }