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"
19 #if defined(mingw32_HOST_OS)
20 #include "win32/seh_excn.h"
25 # include "Printer.h" /* for printing */
29 # include "Parallel.h"
30 # include "ParallelRts.h"
34 #if defined(GRAN) || defined(PAR)
35 # include "GranSimRts.h"
42 extern void __stginit_ZCMain(void);
45 static char **progargv;
47 /* Hack: we assume that we're building a batch-mode system unless
50 #ifndef INTERPRETER /* Hack */
51 static void real_main(void)
54 SchedulerStatus status;
55 /* all GranSim/GUM init is done in startupHaskell; sets IAmMainThread! */
57 startupHaskell(progargc,progargv,__stginit_ZCMain);
59 /* kick off the computation by creating the main thread with a pointer
60 to mainIO_closure representing the computation of the overall program;
61 then enter the scheduler with this thread and off we go;
63 the same for GranSim (we have only one instance of this code)
65 in a parallel setup, where we have many instances of this code
66 running on different PEs, we should do this only for the main PE
67 (IAmMainThread is set in startupHaskell)
73 { /* a wait loop to allow attachment of gdb to UNIX threads */
76 for (i=0, s=0; i<(nat)RtsFlags.ParFlags.wait; i++)
77 for (j=0; j<1000000; j++)
81 belch("Passed wait loop"));
84 if (IAmMainThread == rtsTrue) {
86 debugBelch("==== [%x] Main Thread Started ...\n", mytid));
88 /* ToDo: Dump event for the main thread */
89 status = rts_mainLazyIO((HaskellObj)mainIO_closure, NULL);
91 /* Just to show we're alive */
93 debugBelch("== [%x] Non-Main PE enters scheduler via taskStart() without work ...\n",
96 /* all non-main threads enter the scheduler without work */
98 status = Success; // declare victory (see shutdownParallelSystem)
103 /* ToDo: Dump event for the main thread */
104 status = rts_mainLazyIO(mainIO_closure, NULL);
106 # else /* !PAR && !GRAN */
108 /* ToDo: want to start with a larger stack size */
110 Capability *cap = rts_lock();
111 cap = rts_evalLazyIO(cap,(HaskellObj)(void *)mainIO_closure, NULL);
112 status = rts_getSchedStatus(cap);
113 taskTimeStamp(myTask());
117 # endif /* !PAR && !GRAN */
119 /* check the status of the entire Haskell computation */
122 errorBelch("main thread exited (uncaught exception)");
123 exit_status = EXIT_KILLED;
126 errorBelch("interrupted");
127 exit_status = EXIT_INTERRUPTED;
130 exit_status = EXIT_SUCCESS;
134 errorBelch("main thread PE killed; probably due to failure of another PE; check /tmp/pvml...");
135 exit_status = EXIT_KILLED;
139 barf("main thread completed with invalid status");
141 shutdownHaskellAndExit(exit_status);
143 int main(int argc, char *argv[])
145 /* We do this dance with argc and argv as otherwise the SEH exception
146 stuff (the BEGIN/END CATCH below) on Windows gets confused */
150 #if defined(mingw32_HOST_OS)
154 #if defined(mingw32_HOST_OS)
157 return 0; /* not reached, but keeps gcc -Wall happy */
159 # endif /* BATCH_MODE */