1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team 1998-2000
5 * Main function for a standalone Haskell program.
7 * ---------------------------------------------------------------------------*/
9 #define COMPILING_RTS_MAIN
11 #include "PosixSource.h"
23 # include "Printer.h" /* for printing */
27 # include "Parallel.h"
28 # include "ParallelRts.h"
32 #if defined(GRAN) || defined(PAR)
33 # include "GranSimRts.h"
40 extern void __stginit_ZCMain(void);
42 /* Hack: we assume that we're building a batch-mode system unless
45 #ifndef INTERPRETER /* Hack */
46 int main(int argc, char *argv[])
49 SchedulerStatus status;
50 /* all GranSim/GUM init is done in startupHaskell; sets IAmMainThread! */
52 #if defined(PROFILING) || defined(mingw32_HOST_OS)
53 /* mingw32 and PROFILING (still) define __stginits in .text */
54 startupHaskell(argc,argv,__stginit_ZCMain);
56 startupHaskell(argc,argv,NULL);
59 /* Register this thread as a task, so we can get timing stats about it */
60 #if defined(RTS_SUPPORTS_THREADS)
61 threadIsTask(osThreadId());
64 /* kick off the computation by creating the main thread with a pointer
65 to mainIO_closure representing the computation of the overall program;
66 then enter the scheduler with this thread and off we go;
68 the same for GranSim (we have only one instance of this code)
70 in a parallel setup, where we have many instances of this code
71 running on different PEs, we should do this only for the main PE
72 (IAmMainThread is set in startupHaskell)
78 { /* a wait loop to allow attachment of gdb to UNIX threads */
81 for (i=0, s=0; i<(nat)RtsFlags.ParFlags.wait; i++)
82 for (j=0; j<1000000; j++)
86 belch("Passed wait loop"));
89 if (IAmMainThread == rtsTrue) {
91 debugBelch("==== [%x] Main Thread Started ...\n", mytid));
93 /* ToDo: Dump event for the main thread */
94 status = rts_mainLazyIO((HaskellObj)mainIO_closure, NULL);
96 /* Just to show we're alive */
98 debugBelch("== [%x] Non-Main PE enters scheduler via taskStart() without work ...\n",
101 /* all non-main threads enter the scheduler without work */
103 status = Success; // declare victory (see shutdownParallelSystem)
108 /* ToDo: Dump event for the main thread */
109 status = rts_mainLazyIO(mainIO_closure, NULL);
111 # else /* !PAR && !GRAN */
113 /* ToDo: want to start with a larger stack size */
115 status = rts_evalLazyIO((HaskellObj)mainIO_closure, NULL);
118 # endif /* !PAR && !GRAN */
120 /* check the status of the entire Haskell computation */
123 errorBelch("main thread exited (uncaught exception)");
124 exit_status = EXIT_KILLED;
127 errorBelch("interrupted");
128 exit_status = EXIT_INTERRUPTED;
131 exit_status = EXIT_SUCCESS;
135 errorBelch("main thread PE killed; probably due to failure of another PE; check /tmp/pvml...");
136 exit_status = EXIT_KILLED;
140 barf("main thread completed with invalid status");
142 shutdownHaskellAndExit(exit_status);
143 return 0; /* never reached, keep gcc -Wall happy */
145 # endif /* BATCH_MODE */