Enable two-step allocator on FreeBSD
[ghc.git] / rts / RtsMain.c
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team 1998-2000
4 *
5 * Main function for a standalone Haskell program.
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #define COMPILING_RTS_MAIN
10
11 #include "PosixSource.h"
12 #include "Rts.h"
13 #include "RtsAPI.h"
14
15 #include "RtsUtils.h"
16 #include "RtsFlags.h"
17 #include "Prelude.h"
18 #include "Task.h"
19 #include "Excn.h"
20
21 #if defined(DEBUG)
22 # include "Printer.h" /* for printing */
23 #endif
24
25 // Hack: we assume that we're building a batch-mode system unless
26 // INTERPRETER is set
27
28 #if !defined(INTERPRETER) /* Hack */
29
30 // The rts entry point from a compiled program using a Haskell main
31 // function. This gets called from a tiny main function generated by
32 // GHC and linked into each compiled Haskell program that uses a
33 // Haskell main function.
34 //
35 // We expect the caller to pass ZCMain_main_closure for
36 // main_closure. The reason we cannot refer to this symbol directly
37 // is because we're inside the rts and we do not know for sure that
38 // we'll be using a Haskell main function.
39 //
40 // NOTE: This function is marked as _noreturn_ in Main.h
41
42 int hs_main ( int argc, char *argv[], // program args
43 StgClosure *main_closure, // closure for Main.main
44 RtsConfig rts_config) // RTS configuration
45
46 {
47 int exit_status;
48 SchedulerStatus status;
49
50 // See Note: [Windows Unicode Arguments] in rts/RtsFlags.c
51 #if defined(mingw32_HOST_OS)
52 {
53 argv = getUTF8Args(&argc);
54 }
55 #endif
56
57 hs_init_ghc(&argc, &argv, rts_config);
58
59 BEGIN_WINDOWS_VEH_HANDLER
60
61 // kick off the computation by creating the main thread with a pointer
62 // to mainIO_closure representing the computation of the overall program;
63 // then enter the scheduler with this thread and off we go;
64 //
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)
68
69 // ToDo: want to start with a larger stack size
70 {
71 Capability *cap = rts_lock();
72 rts_evalLazyIO(&cap, main_closure, NULL);
73 status = rts_getSchedStatus(cap);
74 rts_unlock(cap);
75 }
76
77 // check the status of the entire Haskell computation
78 switch (status) {
79 case Killed:
80 errorBelch("main thread exited (uncaught exception)");
81 exit_status = EXIT_KILLED;
82 break;
83 case Interrupted:
84 errorBelch("interrupted");
85 exit_status = EXIT_INTERRUPTED;
86 break;
87 case HeapExhausted:
88 exit_status = EXIT_HEAPOVERFLOW;
89 break;
90 case Success:
91 exit_status = EXIT_SUCCESS;
92 break;
93 default:
94 barf("main thread completed with invalid status");
95 }
96
97 END_WINDOWS_VEH_HANDLER
98
99 shutdownHaskellAndExit(exit_status, 0 /* !fastExit */);
100 // No code beyond this point. Dead code elimination will remove it
101 }
102 # endif /* BATCH_MODE */